package bgu.bio.adt;
import java.util.Arrays;
import java.util.Comparator;
import java.util.Iterator;
import bgu.bio.io.file.json.JSONArray;
import bgu.bio.io.file.json.JSONException;
import bgu.bio.io.file.json.JSONObject;
public class FixedStepRangesTable implements RangesTable {
// private Range dummy;
private Range[] locatingArray;
private Comparator<Range> comp;
private final double step;
private final double first;
private final double last;
private final double pieces;
private String name;
public FixedStepRangesTable(double first, double last, double step) {
this.step = step;
this.last = last;
this.first = first;
this.pieces = 1 / this.step;
this.locatingArray = new Range[(int) ((last - first) / step) + 1];
// this.dummy = new Range(-1.0);
for (int i = 0; i < locatingArray.length; i++) {
locatingArray[i] = new Range(first + step * i);
}
this.locatingArray[this.locatingArray.length - 1] = new Range(last);
comp = new RangeComparator();
Arrays.sort(locatingArray, comp);
}
public FixedStepRangesTable(FixedStepRangesTable counters) {
this.step = counters.step;
this.first = counters.first;
this.last = counters.last;
this.pieces = 1 / this.step;
this.locatingArray = new Range[counters.locatingArray.length];
// this.dummy = new Range(-1.0);
for (int i = 0; i < locatingArray.length; i++) {
locatingArray[i] = new Range(counters.locatingArray[i].value);
}
comp = new RangeComparator();
Arrays.sort(locatingArray, comp);
}
public synchronized void mergeInto(FixedStepRangesTable other) {
for (int i = 0; i < this.locatingArray.length; i++) {
this.locatingArray[i].mergeInto(other.locatingArray[i]);
}
}
@Override
public synchronized Range getRange(double value) {
final int valInt = (int) (value);
int ans = (int) ((valInt - this.first) * pieces + (value - valInt)
* pieces);
return locatingArray[ans];
}
@Override
public String toString() {
StringBuilder sB = new StringBuilder();
for (int i = 0; i < locatingArray.length; i++) {
sB.append(locatingArray[i] + "\n");
}
return sB.toString();
}
@Override
public void clear() {
for (int i = 0; i < this.locatingArray.length; i++) {
this.locatingArray[i].clear();
}
}
public synchronized String toJSON() {
StringBuilder sB = new StringBuilder();
sB.append("{");
sB.append("\"step\":");
sB.append(this.step);
sB.append(',');
sB.append("\"first\":");
sB.append(this.first);
sB.append(',');
sB.append("\"last\":");
sB.append(this.last);
sB.append(',');
sB.append("\"rangetable\":[");
for (int i = 0; i < locatingArray.length; i++) {
sB.append(locatingArray[i].toJSON());
if (i < locatingArray.length - 1)
sB.append(',');
// sB.append('\n');
}
sB.append("]}");
return sB.toString();
}
public static FixedStepRangesTable BuildFromJSON(JSONObject json) {
FixedStepRangesTable table = null;
try {
JSONArray a = json.getJSONArray("rangetable");
int len = a.length();
table = new FixedStepRangesTable(json.getDouble("first"),
json.getDouble("last"), json.getDouble("step"));
for (int i = 0; i < len; i++) {
JSONArray b = a.getJSONArray(i);
Range r = table.getRange(b.getDouble(0));
r.setTuplePassed(b.getInt(1));
r.setTupleFailed(b.getInt(2));
}
} catch (JSONException e) {
e.printStackTrace();
}
return table;
}
public static FixedStepRangesTable BuildFromJSON(String json) {
try {
return BuildFromJSON(new JSONObject(json));
} catch (JSONException e) {
e.printStackTrace();
return null;
}
}
/**
* Size of the range table. the amount of ranges in the table.
*
* @return the number of ranges in the table
*/
@Override
public int size() {
return this.locatingArray.length;
}
@Override
public String getName() {
return name;
}
@Override
public void setName(String name) {
this.name = name;
}
@Override
public Iterator<Range> iterator() {
return new RangeTableIterator(locatingArray);
}
}
class RangeTableIterator implements Iterator<Range> {
private Range[] array;
int position;
public RangeTableIterator(Range[] array) {
this.array = array;
this.position = 0;
}
@Override
public boolean hasNext() {
return this.position < array.length;
}
@Override
public Range next() {
Range ans = array[position];
position++;
return ans;
}
@Override
public void remove() {
throw new UnsupportedOperationException("Not implemented");
}
}
class RangeComparator implements Comparator<Range> {
@Override
public int compare(Range o1, Range o2) {
if (o1.value == o2.value)
return 0;
else if (o1.value < o2.value)
return -1;
else
return 1;
}
}