package com.k13n.lt_codes;

import java.util.Random;
import java.util.Arrays;
import java.util.BitSet;
import java.nio.ByteBuffer;

public final class Encoder {

  public interface Callback {
    public boolean call(Encoder encoder, TransmissonPacket packet);
  }

  private static final double DEFAULT_FAILURE_PROBABILITY = 0.01;
  private static final double DEFAULT_C = 0.3333;

  private final int packetSize;
  private final int nPackets;
  private final Random uniformRNG;
  private final RobustSolitonGenerator solitonRNG;
  private final ByteBuffer buffer;
  private final long seed;

  public Encoder(byte[] data, int packetSize) {
    this(data, packetSize, DEFAULT_FAILURE_PROBABILITY, DEFAULT_C);
  }

  public Encoder(byte[] data, int packetSize, double failureProbability, double c) {
    this.packetSize = packetSize;
    this.seed = (long)(Math.random() * 1024 * 5);
    this.nPackets = (int)Math.ceil(data.length / (double)packetSize);
    this.uniformRNG = new Random(this.seed);
    this.solitonRNG = new RobustSolitonGenerator(nPackets, c, failureProbability);

    this.buffer = ByteBuffer.wrap(Arrays.copyOf(data, nPackets * packetSize),
                                  0, nPackets * packetSize);
  }

  public long getSeed() {
    return this.seed;
  }

  public int getNPackets() {
    return this.nPackets;
  }

  public void encode(Callback callback) {
    boolean abort = false;
    while(!abort) {
      try {

        int d = solitonRNG.next();
        BitSet xorSet = null;

        int[] neighbours = new int[d];

        for(int i = 0; i < d; i++)
        {
          int packetIndex = uniformRNG.nextInt(this.nPackets);
          int pos = packetIndex * this.packetSize;
          neighbours[i] = packetIndex;
          this.buffer.position(pos);
          BitSet bitSet = BitSet.valueOf(this.buffer).get(0, this.packetSize * 8);
          if(xorSet == null)
            xorSet = bitSet;
          else
            xorSet.xor(bitSet);
        }

        byte[] packetData = xorSet.toByteArray();
        TransmissonPacket packet = new TransmissonPacket(neighbours, packetData);
        abort = callback.call(this, packet);


      } catch(Exception e) {
        /* FIXME*/
        e.printStackTrace();
      }

    }


  }
}

@@ -339,38 +339,35 @@
 te static final 
-double
+int
  DEFAULT_C = 0.3
@@ -363,18 +363,18 @@
 ULT_
-C = 0.3333
+SPIKE = 50
 ;%0A%0A 
@@ -695,17 +695,21 @@
 DEFAULT_
-C
+SPIKE
 );%0A  %7D%0A%0A
@@ -785,16 +785,17 @@
 ty, 
-double c
+int spike
 ) %7B%0A
@@ -1052,17 +1052,21 @@
 ackets, 
-c
+spike
 , failur

Use the spike parameter instead of the obscure c parameter