/**
Copyright 2015 Tim Engler, Rareventure LLC
This file is part of Tiny Travel Tracker.
Tiny Travel Tracker is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Tiny Travel Tracker is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Tiny Travel Tracker. If not, see <http://www.gnu.org/licenses/>.
*/
package com.rareventure.gps2.database;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.Iterator;
import java.util.TimeZone;
import android.database.Cursor;
import android.util.Log;
import com.rareventure.android.DbUtil;
import com.rareventure.android.Util;
import com.rareventure.android.Util.LongComparator;
import com.rareventure.android.database.Cache;
import com.rareventure.android.database.DbDatastoreAccessor;
import com.rareventure.gps2.GTG;
import com.rareventure.gps2.GpsTrailerCrypt;
/**
* Set of all time zone data points
*/
public class TimeZoneTimeSet {
private static final LongComparator<TimeZoneTimeRow> TIME_COMPARATOR = new Util.LongComparator<TimeZoneTimeRow>() {
@Override
public int compare(TimeZoneTimeRow t, long key) {
if(t.getTime() < key)
return -1;
else if(t.getTime() > key)
return 1;
return 0;
}
};;
ArrayList<TimeZoneTimeRow> data = new ArrayList<TimeZoneTimeRow>();
private DbDatastoreAccessor<TimeZoneTimeRow> dbA;
private int nextRowId = -1;
public TimeZoneTimeSet() {
dbA = new DbDatastoreAccessor<TimeZoneTimeRow>(
TimeZoneTimeRow.TABLE_INFO);
}
/**
* This will also delete items that are unnecessary repeats.
*/
public void loadSet()
{
data.clear();
GTG.db.beginTransaction();
try {
boolean isFirst = true;
TimeZoneTimeRow lastTztr = null;
Cursor c = dbA.query(null, "_id");
while(c.moveToNext())
{
TimeZoneTimeRow tztr = new TimeZoneTimeRow();
dbA.readRow(tztr, c);
if(!isFirst)
{
if(tztr.isTimeZoneEqual(lastTztr))
{
/* ttt_installer:remove_line */Log.d(GTG.TAG,"Deleting duplicate tztr "+lastTztr+", "+tztr);
GTG.db.execSQL("delete from time_zone_time where _id = ?", new Object [] {tztr.id});
continue;
}
}
isFirst =false;
data.add(tztr);
lastTztr = tztr;
}
GTG.db.setTransactionSuccessful();
}
finally {
GTG.db.endTransaction();
}
}
/**
* Adds a row to the database and the set. Does not start a transaction.
* Sets an id into the tzt
*/
public void addRowToEnd(TimeZoneTimeRow tzt)
{
if(nextRowId == -1)
nextRowId = dbA.getNextRowId();
if(!data.isEmpty()
&& tzt.getTime() < getLatestRow().getTime())
throw new IllegalStateException("cant add a row before end");
tzt.id = nextRowId++;
data.add(tzt);
// Log.d(GTG.TAG,"adding tzt to end, "+tzt);
dbA.insertRow(tzt);
}
public TimeZoneTimeRow getLatestRow() {
if(data.isEmpty())
return null;
return data.get(data.size() -1);
}
public Iterator<TimeZoneTimeRow> getIterator() {
return data.iterator();
}
public TimeZone getTimeZoneTimeOrNullIfUnknwonOrLocalTime(int timeSec)
{
TimeZoneTimeRow tztr = GTG.tztSet.getTimeZoneCovering(timeSec);
if(tztr != null && tztr.getTimeZone() != null && !tztr.isLocalTimeZone())
return tztr.getTimeZone();
return null;
}
public TimeZoneTimeRow getTimeZoneCovering(int timeSec) {
int index = Util.binarySearch(data, timeSec*1000l, TIME_COMPARATOR);
if(index < 0)
//if less than zero, x = -(insertion point) -1, so
// insertion point = -x - 1
// the one before the insertion point is the time zone we're looking
// for (with a time that is the greatest and also less than timeSec)
{
//the time is before the first timezone
if(-index -2 < 0)
return null;
else
return data.get(-index -2);
}
//it exactly matches a timezone
return data.get(index);
}
}