var GanjaGears = function() {}
GanjaGears.runningApp = null;
GanjaGears.runningVersions = null;

GanjaGears.Tools = function() {}
GanjaGears.Tools.textContainer = 'turboModeSwitch';
GanjaGears.Tools.debugLevel = 3;

GanjaGears.DB = function() {}
GanjaGears.DB.db = null;
GanjaGears.DB.dbName = 'ged';
GanjaGears.DB.currentVersions = {
			'savedForms'	: 0,
			'postCodes'		: 0,
			'settings'		: 0,
			'tags'			: 0,
			'tagCheckLog'	: 0,
			'images'		: 0,
			'imageUrls'		: 0,
			'posts'			: 0,
			'postImages'	: 0
		};


GanjaGears.Tools.checkGears = function()
{
	var msg = 'Checking if we have Gears: ';
	var ret = window.google && google.gears;
	msg += ret ? 'we have' : 'we don\'t have';
	GanjaGears.Tools.debug( msg );
	return ret;
}
	
GanjaGears.Tools.noGears = function()
{
	GanjaGears.Tools.debug( 'We have no Gears' );
	GanjaGears.Tools.setText( '<a href="#" onclick="GanjaGears.Tools.showInstall(); return false;">Turbo is OFF</a>' );
	return false;
}
		
GanjaGears.Tools.setText = function( msg, container )
{
	if( !container ) container = GanjaGears.Tools.textContainer; 
	$( container ).innerHTML = msg;
}
	
GanjaGears.Tools.showInstall = function()
{
	GanjaGears.Tools.setText( '<a href="http://gears.google.com/?action=install&return=' + location.href + '">Install Google Gears</a>' );
}

GanjaGears.Tools.debug = function( message, level )
{
	if( !level ) level = 0;
	if( level < GanjaGears.Tools.debugLevel ) return;
	var colors = [ 'black', 'green', 'red' ];
	var logCont = $( 'GanjaGearsLogContainer' ); 
	if( !logCont )
	{
		logCont = new Element( 'div', { 'id' : 'GanjaGearsLogContainer', 'style' : 'position: absolute; width: 300px; height: 150px; font-size: 9px; overflow: auto; top: 100px; right: 100px; border: 1px black solid; padding: 2px;' } );
		var bodies = document.getElementsByTagName( 'body' );
		var body = bodies[0];
		body.appendChild( logCont );
	}
	var date = new Date();
	logCont.innerHTML += '<p style="color: ' + colors[level] + '; margin: 0px 0px 2px 0px; padding: 0px; border-bottom: 1px black solid;">' + date.getHours() +  ':' + date.getMinutes() + ':' + date.getSeconds() + '.' + date.getMilliseconds() + ' ' + message + "</p>\n"; 
}

GanjaGears.Tools.gatherFormData = function( formId, exceptions )
{
	if( !exceptions ) exceptions = [];
	var els = $( formId ).getElements();
	var obj = {};
	for( var i = 0; i < els.length; i++ )
	{
		var el = els[i];
		if( !el.name || exceptions.indexOf( el.name ) != -1 ) continue;
		var val = $F( el );
		if( val == null ) continue;
		obj[el.name] = $F( el );
	}
	return obj;
}
	
GanjaGears.Tools.loadFormData = function( formId, obj, exceptions )
{
	if( !exceptions ) exceptions = [];
	if( !obj ) return;
	var els = $( formId ).getElements();
	for( var i = 0; i < els.length; i++ )
	{
		var el = els[i];
		if( !el.name || exceptions.indexOf( el.name ) != -1 ) continue;
		var tagName = el.tagName.toLowerCase();
		var val = null;
		if( obj[el.name] ) val = obj[el.name];
		if( tagName == 'select' )
		{
			for( var j = 0; j < el.options.length; j++ )
			{
				if( el.options[j].value == val )
				{
					el.selectedIndex = j;
					break;
				}
			}
		}
		else if( tagName == 'textarea' ) el.value = val;
		else if( tagName == 'input' )
		{
			var type = el.type
			if( type == 'submit' || type == 'button' ) continue;
			if( type == 'checkbox' ) el.checked = ( val != null );
			else el.value = val;
		}
	}
}

GanjaGears.Tools.saveForm = function( formId, code )
{
	GanjaGears.DB.saveObj( code, GanjaGears.Tools.gatherFormData( formId ) );
}

GanjaGears.Tools.loadForm = function( formId, code )
{
	GanjaGears.Tools.loadFormData( formId, GanjaGears.DB.loadObj( code ) );
}

GanjaGears.Tools.getDate = function( sqlDate )
{
	var match = sqlDate.match( /([0-9]{4})-([0-9]{2})-([0-9]{2}) ([0-9]{2}):([0-9]{2}):([0-9]{2})/ );
	var ret = new Date();
	ret.setUTCFullYear( parseInt( match[1] ) );
	ret.setUTCMonth( parseInt( match[2] ) - 1 );
	ret.setUTCDate( parseInt( match[3] ) );
	ret.setUTCHours( parseInt( match[4] ) );
	ret.setUTCMinutes( parseInt( match[5] ) );
	ret.setUTCSeconds( parseInt( match[6] ) );
	return ret;
}

GanjaGears.DB.initDB = function( DBName )
{
	if( !DBName ) DBName = GanjaGears.DB.dbName;
	var db = google.gears.factory.create('beta.database');
	db.open();
	return db;
}

GanjaGears.DB.getDB = function( DBName )
{
	if( !DBName ) DBName = '';
	if( GanjaGears.DB.db == null )
	{
		GanjaGears.DB.db = GanjaGears.DB.initDB();
		GanjaGears.DB.checkConsistency( GanjaGears.DB.db );
	}
	return GanjaGears.DB.db;
}

GanjaGears.DB.unsetDB = function()
{
	GanjaGears.DB.db = null;
}

GanjaGears.DB.checkConsistency = function( db )
{
	db.execute('CREATE TABLE IF NOT EXISTS tableVersions ( tableName TEXT, version INTEGER DEFAULT 0, UNIQUE( tableName ) )' );
	for( var table in GanjaGears.DB.currentVersions )
	{
		if( typeof table != 'string' ) continue;
		var version = -1;
		var rs = db.execute( 'SELECT version FROM tableVersions WHERE tableName = ?', [table] );
		if( rs.isValidRow() ) version = parseInt( rs.fieldByName( 'version' ) );
		rs.close();
		if( version == -1 )
		{
			rs = db.execute( 'INSERT INTO tableVersions ( tableName ) VALUES ( ? )', [table] );
			rs.close();
			GanjaGears.DB.patches[table + '#0']( db );
			version = 0;
		}
		for( var i = version; i < GanjaGears.DB.currentVersions[table]; i++ ) GanjaGears.DB.patches[table + '#' + i]( db );
		rs = db.execute( 'UPDATE tableVersions SET version = ? WHERE tableName = ?', [GanjaGears.DB.currentVersions[table], table] );
		rs.close();
	}
}

GanjaGears.DB.patches = {
	'savedForms#0' : function( db )
	{
		db.execute( 'CREATE TABLE IF NOT EXISTS savedForms ( formId INTEGER PRIMARY KEY AUTOINCREMENT, code TEXT, json TEXT, date TEXT DEFAULT CURRENT_TIMESTAMP, UNIQUE( code ) )' );
	},
	
	'postCodes#0' : function( db )
	{
		db.execute( 'CREATE TABLE IF NOT EXISTS postCodes ( postId INTEGER, code TEXT )' );
	},
	
	'settings#0' : function( db )
	{
		db.execute( 'CREATE TABLE IF NOT EXISTS settings ( name TEXT, value TEXT )' );
	},
	
	'tags#0' : function( db )
	{
		db.execute( 'CREATE TABLE IF NOT exists tags ( siteId INTEGER, tag TEXT  )' );
	},

	'tagCheckLog#0' : function( db )
	{
		db.execute( 'CREATE TABLE IF NOT exists tagCheckLog ( siteId INTEGER, checkDate TEXT DEFAULT CURRENT_TIMESTAMP  )' );
	},

	'images#0' : function( db )
	{
		db.execute( 'CREATE TABLE IF NOT exists images ( imageId INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT  )' );
	},
	
	'imageUrls#0' : function( db )
	{
		db.execute( 'CREATE TABLE IF NOT exists imageUrls ( imageUrlId INTEGER PRIMARY KEY AUTOINCREMENT, imageId INTEGER, url TEXT, width INTEGER, height INTEGER )' );
	},
	
	'posts#0' : function( db )
	{
		db.execute( 'CREATE TABLE IF NOT exists posts ( postId INTEGER, tag TEXT  )' );
	},

	'postImages#0' : function( db )
	{
		db.execute( 'CREATE TABLE IF NOT exists postImages ( postId INTEGER, imageId INTEGER  )' );
	}

}

GanjaGears.DB.saveObj = function( code, obj )
{
	var saved = GanjaGears.DB.loadObj( code );
	var db = GanjaGears.DB.getDB();
	var sql = '';
	if( saved ) sql = 'UPDATE savedForms SET json = ? WHERE code = ?';
	else sql = 'INSERT INTO savedForms (json, code) VALUES (?, ?)';
	try
	{
		var rs = db.execute( sql, [Object.toJSON(obj ), code] );
		rs.close();
	}
	catch( ex )
	{
		return false;
	}
	return true;
}

GanjaGears.DB.loadObj = function( code )
{
	var db = GanjaGears.DB.getDB();
	var re = db.execute( 'SELECT json FROM savedForms WHERE code = ?', [code] );
	var ret = null;
	try
	{
		if( re.isValidRow() ) ret = eval( '(' + re.fieldByName( 'json' ) + ')' );
	}
	catch( ex )
	{
		GanjaGears.Tools.debug( 'Invalid JSON data' );
	}
	re.close();
	return ret;
}
