/bs/encode.go
package bs

import (
    "sort"

    "bytex64.net/code/bitsmash/packet"
)

type scanFunc func(pixels []uint8) packet.Packet

var scanFuncs []scanFunc = []scanFunc {
    packet.ScanRLE,
    packet.ScanBinaryPattern,
    packet.ScanDirect,
}

func findAllEncodeLengths(pixels []uint8, steps int) []packet.PacketRun {
    results := make([]packet.PacketRun, 0)
    if len(pixels) == 0 {
        return results
    }

    for _, scan := range(scanFuncs) {
        pkt := scan(pixels)
        if pkt == nil {
            continue
        }
        pkt_length := pkt.Length()
        pkt_bytes := pkt.ByteLength()
        if steps > 1 && len(pixels) > pkt_length {
            rec_results := findAllEncodeLengths(pixels[pkt_length:], steps - 1)
            for _, r := range(rec_results) {
                results = append(results, packet.PacketRun{r.Length + pkt_length, r.Bytes + pkt_bytes, r.Depth + 1, pkt})
            }
        } else {
            results = append(results, packet.PacketRun{pkt_length, pkt_bytes, 1, pkt})
        }
    }

    return results
}

func findOptimalEncoding(pixels []uint8, optimize int) packet.Packet {
    results := findAllEncodeLengths(pixels, optimize)
    sort.Sort(packet.ByPacketEfficiency(results))
    /*
    fmt.Printf("optimal encodings (%d bytes remain):\n", len(pixels))
    for _, v := range(results) {
        fmt.Println(v)
    }
    */
    return results[0].Head
}

func findRepeats(packetlist []packet.Packet) []packet.Packet {
    outlist := make([]packet.Packet, 1, len(packetlist))
    outlist[0] = packetlist[0]

    for i := 1; i < len(packetlist); {
        pkt := packet.ScanRepeat(packetlist, i)
        if pkt != nil {
            outlist = append(outlist, pkt)
            rpkt := pkt.(*packet.RepeatPacket)
            i += rpkt.Count()
        } else {
            outlist = append(outlist, packetlist[i])
            i++
            continue
        }
    }

    return outlist
}