/***
 * localDbVersion
 * variable to decide whether need to recreate the local db schema
 */
function getLocalDbVersion() {
	return "6.5.1.7";
}

var WEBSQL_PURGE_THRESHOLD = 3 * 24 * 3600; // 3 days

var db;

var messageCacheErrorHandler = function(tx, err) {
	console.error(err);
}

function jsonToString(jsonObj) {
	if(!jsonObj) return '';
	var str = JSON.stringify(jsonObj);	
	return btoa(unescape(encodeURIComponent( str )));
}

function strToJson(jsonStr) {
	if(!jsonStr) return null;
	return JSON.parse( decodeURIComponent(escape(window.atob( jsonStr ))) );
}

function initLocalDatabase()
{
	if(typeof(window.openDatabase)=='undefined') {
		console.warn("your browser dosn't support WebSQL!");
		return false;
	}

	db = openDatabase('atmail-mobile', '', 'Atmail Mobile UI', 5*1024*1024);

	if(db.version && db.version != getLocalDbVersion() ) {
		db.transaction(function(tx) {

			tx.executeSql('DROP TABLE IF EXISTS messageCache', [], null, messageCacheErrorHandler);
		})

		db.changeVersion(db.version, getLocalDbVersion());
	}

	db.transaction(function (tx) {
		tx.executeSql(
			'CREATE TABLE IF NOT EXISTS messageCache(' +
				'   id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT ,' +
				'   account VARCHAR(64) NOT NULL,' +
				'   uid INTEGER NOT NULL,' +
				'   folder VARCHAR(255) NOT NULL,' +
				'   message TEXT NOT NULL,' +
				'   timeStored datetime,' +
				'   UNIQUE(account, uid, folder)' +
			')',
			[],
			null,
			messageCacheErrorHandler
		);

		var timeDeleteThreshold = Math.round(Date.now()/1000) - WEBSQL_PURGE_THRESHOLD;
		tx.executeSql("DELETE from messageCache where timeStored<date(?,'unixepoch')", [timeDeleteThreshold], null, messageCacheErrorHandler);

	});

	return true;
}

initLocalDatabase();

var messageCache_sqlite = {

	load : function(uid, folder, callback) {
		var account = $mobile.getAccount();
		if(!account) {
			console.error('cannot load without sucessfully login');
			callback && callback(null);
			return;
		}

		db.transaction(function(tx) {
			tx.executeSql('select message from messageCache where uid=? and folder=? and account=?', [uid, folder, account],
				function(tx, result){

					var message = null;
					if(result.rows.length) {
						var row = result.rows.item(0);
						var str = row.message;
						message = JSON.parse( decodeURIComponent(escape(window.atob( str ))) );
					}

					if(callback) callback(message);

				},
				messageCacheErrorHandler
			)
		})
	},

	save : function(uid, folder, message) {
		var account = $mobile.getAccount();
		if(!account) {
			console.error('cannot save without sucessfully login');
			return;
		}

		if(!uid || !folder || !message) {
			console.error('cannot save null message!');
			return;
		}

		try{
			var str = JSON.stringify(message);
			message = btoa(unescape(encodeURIComponent( str )));
		}
		catch(err) {
			console.error(err, message);
			return;
		}


		db.transaction(function(tx) {
			tx.executeSql("DELETE FROM messageCache where account=? and uid=? and folder=?", [uid, account, folder],
				null,
				messageCacheErrorHandler
			);

			var sql = "REPLACE INTO messageCache (uid, account, folder, message, timeStored) values(?,?,?,?,datetime('now'))";
			var param = [uid, account, folder, message];
			tx.executeSql(sql, param, null, messageCacheErrorHandler);

		})
	},

	getUncachedIDs : function(UIDs, folder, callback) {

		var account = $mobile.getAccount();
		if(!account) {
			console.error('cannot load without sucessfully login');
			callback && callback(UIDs);
			return;
		}

		if(!(UIDs instanceof Array)) {
			console.error('UIDs is not an array');
			//console.trace();
		}

		var sqlResponded = [];
		var newIDs = [];

		db.transaction(function(tx) {

			var sql = "select uid from messageCache where uid=? and folder=? and account=?";

			$.each(UIDs, function(k,v) {

				var param = [v, folder, account];

				tx.executeSql(sql, param,
					function(tx, result){
						sqlResponded.push( v );

						if(result.rows.length!=1) {
							newIDs.push(v);
						}

					},
					messageCacheErrorHandler
				)

			})

		})

		var timeCounter = 0;
		db.intervalHandle = setInterval(function(){
			++timeCounter;

			if(sqlResponded.length == 5 || timeCounter>200) {
				clearInterval(db.intervalHandle);
				db.intervalHandle = null;

                if(callback) callback(newIDs);
			}

		},10);

	},

	deleteCache : function(uid, folder) {
		var account=$mobile.getAccount();
		if(!account) return;

		db.transaction(function(tx) {

			var sql = "delete from messageCache where uid=? and folder=? and account=?";
			var param = [uid, folder, account];

			tx.executeSql(sql, param, null, messageCacheErrorHandler)

		})
	}

};


var messageCache_localstorage = {

	uidToKey : function(uid, folder) {
		 return $mobile.getAccount() + uid + folder;
	},

	load : function(uid, folder, callback) {
		var message = localStorage.getItem( this.uidToKey(uid, folder) );
		if(message) {
			message = JSON.parse(message);
		}
        if(callback) callback(message);
	},

	save : function(uid, folder, message) {
		try{
			localStorage.setItem( this.uidToKey(uid, folder), JSON.stringify(message) );
		}
		catch(err) {
			console.error(err);
		}
	},

	getUncachedIDs : function(UIDs, folder, callback) {
		callback && callback(UIDs);
	},

	deleteCache : function(uid, folder) {
		console.warn('delete local cache has not implemented yet for firefox.')
	}


};

var messageCache = db? messageCache_sqlite : messageCache_localstorage;


