package org.tyszecki.rozkladpkp.pln;
import java.util.ArrayList;
import java.util.BitSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.TreeMap;
import org.tyszecki.rozkladpkp.pln.PLN.Availability;
import android.text.format.Time;
import android.util.Log;
public class DayUtils {
private PLN pln;
private int count = -1;
private int connections = -1;
//Mapa: Numer dnia → Lista połączeń w dniu (identyfikatory połączeń)
private Map<Integer, List <Integer>> daysMap = null;
public DayUtils(PLN input) {
pln = input;
}
public Map<Integer, List <Integer>> getDaysMap()
{
if(daysMap == null)
count();
return daysMap;
}
public Time getDay(int number)
{
Time ret = new Time(pln.sdate);
ret.monthDay += number;
ret.normalize(false);
return ret;
}
/**
* Zwraca liczbę dni o których są dane w rozkładzie.
* Tylko tych dni, w które jeżdżą pociągi.
*/
public int count()
{
if(count == -1)
{
connections = 0;
//TreeMap gwarantuje posortowanie wg klucza
//TODO: Tutaj można dużo zoptymalizować, zmieniając sposób iteracji (po dostępnościach)
daysMap = new TreeMap<Integer, List<Integer>>();
for(int c = 0; c < pln.conCnt; ++c)
{
Availability a = pln.connections[c].getAvailability();
int j = a.dOffset*8;
BitSet t = a.bitset();
int len = a.bsLength();
for(int i = 0; i < len; i++,j++)
{
boolean av = t.get(i);
if(av)
{
if(!daysMap.containsKey(j))
daysMap.put(j, new ArrayList<Integer>());
daysMap.get(j).add(c);
connections++;
}
}
}
}
count = daysMap.size();
return count;
}
public int totalConnectionCount()
{
if(connections == -1)
count();
return connections;
}
public Iterable<Connection> getConnectionIterator()
{
return new Iterable<Connection>() {
@Override
public Iterator<Connection> iterator() {
return new ConnectionIterator();
}
};
}
public class ConnectionIterator implements Iterator<Connection>
{
private Object[] array;
private int connectionIndex, dayIndex, connectionsPresentDay = 0;
Entry<Integer, List<Integer>> item = null;
public ConnectionIterator() {
array = getDaysMap().entrySet().toArray();
dayIndex = 0;
connectionIndex = 0;
if(hasNext())
nextDay();
}
@Override
public boolean hasNext() {
//Zwróć prawdę, jeśli jest jeszcze jakiś dzień, lub nie skończyliśmy iterować obecnego dnia
return dayIndex < array.length || connectionIndex < connectionsPresentDay;
}
private void nextDay()
{
item = (Entry<Integer, List<Integer>>) array[dayIndex++];
connectionsPresentDay = item.getValue().size();
}
@Override
public Connection next() {
if(connectionIndex >= connectionsPresentDay)
{
connectionIndex = 0;
nextDay();
}
Log.i("RozkladPKP", "IDX: "+Integer.toString(connectionIndex)+", D:"+item.getKey().toString());
return new Connection(pln.connections[item.getValue().get(connectionIndex++)], item.getKey());
}
@Override
public void remove() {}
}
}