/*******************************
 * (C) Stephen Rees
 * DTAG-Gears Javascript
 *
 * The Javascript for managing DTAGgears support
 * 
 * SVN tags
 * $Author: valorin $
 * $Revision: 650 $
 * $Date: 2008-02-15 11:59:06 +1100 (Fri, 15 Feb 2008) $
 *******************************/ 

/*
 *  Setup Variables
 */
var localServer;
var db;
var store;
var storeName = "dtagGearsBeta";
var manifestUrl = urlroot+"manifest.json";
var isOffline = false;
var offlineStatus = "DTAG Offline Mode";
var onlineStatus = "Online";
var gearsSettings = new Array();
var importedPages = 0;
var gears = new Array();
var queryid = 0;
var timeUpdateStatus	= 1000;		 // Updates - Manifest file
var timeOnlineCheck		= 60000 * 1;	 // Check user is online
var timeNewPage 		= 10000;	 // Check for new pages - import
var timeSlowNewPage		= 60000 * 5;	 // Check for new pages - periodically

var userInfoOffline = "<p><strong>- Offline -</strong><br /><a href='#' onclick='javascript:toggleDebug(); return false;' id='toggledebug'>Enable Debug Log</a></p>";
var pageInfoOffline = "<p><strong>- DTAGgears Offline mode -</strong><br />" +
						"DTAG is now in Read Only mode.<br />" +
						"You can read through any page within your local database.<br />" +
						"<a href='#' onclick='javascript:checkOnline(); return false;'>Check for Online connection?</a>" +
						"</p>";


function dtagGearsStart(){

	// Check Gears is installed
	if (!window.google || !google.gears){
		gears['loading'] = false;

		// Gears is not installed.
		setStatus("Gears not installed - <a href='http://gears.google.com/?action=install" +
			"&message=Gears%20will%20allow%20you%20to%20read%20through%20DTAG%20while%20offline" +
			"&return="+location.href+"'>install</a>");
		addDebug("Gears is not installed.");
		addDebug("Ending script.");
	}else{
		gears['loading'] = true;
	
		// Gears is installed
		setStatus("Gears support loading...");
		addDebug("Gears are installed.");
		addDebug("Seting components for use.");
		
		if (!  startFactories()  ) {  return;  }
		
		gearsEnabled = true;
		isOffline = true;
		
		// Make links check online status first
		tagNonPageLinks();
		
		addDebug("**************");
		
		// Check online status
		checkOnline();
	}
}


function startFactories(){

	// Create localserver - for local resources
	try {
		localServer = google.gears.factory.create("beta.localserver","1.0");
		store = localServer.createManagedStore("dtagGearsBeta");
		store.manifestUrl = manifestUrl; // Point to Manifest file
		addDebug("Manifest version: "+store.currentVersion);
		addDebug("Factory: store/localserver setup successful");
		
		// Setup DB
		db = google.gears.factory.create('beta.database', '1.0');
		if (!  initiateDatabase()  ) {  return;  }
		addDebug("Factory: database setup successful");
		
		return true;
	}catch (error) {
		addDebug("Something failed when setting up. Aborting.");
		addDebug("Likely Gears support denied.");
		setStatus("Gears support disabled.");
		return false;
	}
}


function initiateDatabase(){

	if (db) {
		try {
			db.open('dtag_gears');
			
			//db.execute('DROP TABLE IF EXISTS dtag_settings');
			//db.execute('DROP TABLE IF EXISTS dtag_pages');
			
			db.execute('CREATE TABLE IF NOT EXISTS dtag_pages' +
				' (pageid INTEGER PRIMARY KEY,' + 
				' source LONGTEXT,' + 
				' info LONGTEXT,' +
				' title VARCHAR(255),' +
				' timestamp DATETIME)');
			
			db.execute('CREATE TABLE IF NOT EXISTS dtag_settings' +
				' (key VARCHAR(255) PRIMARY KEY,' +
				' value VARCHAR(255))');
			
			// Load Gears Settings
			var result = db.execute("SELECT * FROM dtag_settings");
			if (!result.isValidRow()){
				db.execute("INSERT INTO dtag_settings (key, value) VALUES ('latest', '00-00-00 00:00:01')");
				db.execute("INSERT INTO dtag_settings (key, value) VALUES ('timeout', "+timeNewPage+")");
				db.execute("INSERT INTO dtag_settings (key, value) VALUES ('lastpage', 1)");
				result.close();
				result = db.execute("SELECT * FROM dtag_settings");
			}
			while (result.isValidRow()){
				gearsSettings[result.fieldByName("key")] = result.fieldByName("value");
				addDebug("Loading Setting: "+result.fieldByName("key")+" = "+result.fieldByName("value"));
				result.next();
			}
			result.close();
			
			return true;
		}catch (error){
		
			addDebug("Caught exception when initiating DB");
		}
	}
	addStatus("Failed to initiate Gears Database, please try again later.");
	addDebug("Database initiation failed.");

	return false;
}


function storeUpdateStatus(){

	store.checkForUpdate();
	storeUpdateStatusTimer();

}


function storeUpdateStatusTimer(){

	// Loading and downloading updates
	if (store.updateStatus == 1 || store.updateStatus == 2){
		addDebug("... resources updating");
		setTimeout("storeUpdateStatusTimer()", timeUpdateStatus);
		
	// Update failed
	}else if (store.updateStatus == 3){
		addDebug("Manifest failed: "+store.lastErrorMessage);
		
	// Update successful
	}else if(store.updateStatus == 0){
		addDebug("Manifest Loaded successfully!");
	}
}


function tagNonPageLinks(){

	var anchors = document.getElementsByTagName("a");
	for (var i = 0; i < anchors.length; i++){
		if (anchors[i].className != "pagechoice" && anchors[i].href != "#header"){
			anchors[i].addEventListener("click", clickPassThrough, true);
		}
	}
}


function clickPassThrough(event){

	if (typeof event == 'undefined'){
		event = window.event;
	}

	if (isOffline){
		stopDefaultAction(event);
	}

	return false;
}


function checkOnline(){

	addDebug("PING");
	queryid = Math.random();
	jueRequestAbort(urlroot+"?ping="+queryid, null, checkOnlineResponse, setOfflineResponse);
}


function checkOnlineResponse(response){

	addDebug("PONG");
	gears['loading'] = false; // We've got the response back, and are ready to work.
	if (queryid == response){
	
		// if back from Offline, check db & manifest
		if (isOffline){
			requestNewPages();
			storeUpdateStatus()
		}
		setOnline();
	}else{
		setOffline();
	}
	setTimeout("checkOnline()", timeOnlineCheck);
}


function requestNewPages(){

	setTimeout("getNewPages()", gearsSettings['timeout']);
}


function getNewPages(){

	if (isOffline) {  return;  }
	
	addDebug("Initiate getNewPages()");
	setStatus("Syncing DB to local...");
	
	jueRequestAbort(urlroot+"?gears&getlatest="+gearsSettings['latest'], null, getNewPagesResponse, setOfflineResponse);
}


function getNewPagesResponse(response){
	
	addDebug("Parsing newPages response");
	
	// Done downloading the periodic updates - slow it down
	if (response == "DONE"){
	
		addDebug("Slowing down getNewPages");
		gearsSettings['timeout'] = timeSlowNewPage;
		requestNewPages();
		db.execute("REPLACE INTO dtag_settings (value, key) VALUES (?, 'timeout')", [gearsSettings['timeout']]);
	
	// parse the periodic update response
	}else{
		// Incase we have some issues with the import
		try {
		
			var pages = JSON.parse(response);
			gearsSettings['latest'] = pages['latest'];
			for (var i in pages){
				if (i != "latest"){
					savePage(pages[i]);
					importedPages++;
				}
			}
			addDebug("New pages Parsed");
			addDebug("Total imported pages: "+importedPages);
			requestNewPages();
			setStatus(onlineStatus);
			db.execute("REPLACE INTO dtag_settings (value, key) VALUES (?, 'latest')", [gearsSettings['latest']]);
		} catch (error) {
			
			addDebug("Had an error importing!!");
		}
	}
}


function saveGearsLastPage(pagenum){

	if (gearsEnabled){
		db.execute("REPLACE INTO dtag_settings (value, key) VALUES (?, 'lastpage')", [pagenum]);
	}
}


function setOfflineResponse(){

	gears['loading'] = false; // We've got the response back, and are ready to work.
	setTimeout("checkOnline()", timeOnlineCheck);
	setOffline();
}


function savePage(pagedata){

	var result = db.execute("SELECT pageid FROM dtag_pages WHERE pageid = ?", [pagedata['pageid']]);
	rows = 0;
	while (result.isValidRow()){
		rows++;
		result.next();
	}
	
	if (rows == 0){
		addDebug("Adding pageid: "+pagedata['pageid']+" to DB");
		db.execute("INSERT INTO dtag_pages (pageid, source, info, title, timestamp) VALUES (?, ?, ?, ?, ?)", [pagedata['pageid'], pagedata['source'], pagedata['pageinfo'], pagedata['title'], pagedata['timestamp']]);
	}else{
		addDebug("Updating pageid: "+pagedata['pageid']+" in DB");
		db.execute("UPDATE dtag_pages SET source = ?, info = ?, title = ?, timestamp = ? WHERE pageid = ?", [pagedata['source'], pagedata['pageinfo'], pagedata['title'], pagedata['timestamp'], pagedata['pageid']]);
	}
	result.close();
}


function loadOfflinePage(pagenum, pagediv){

	var result = db.execute("SELECT * FROM dtag_pages WHERE pageid = ?", [pagenum]);
	
	if (result.isValidRow()){
	
		addDebug("Loading offline page:"+pagenum);
		var pagedata = new Array();
		pagedata['source'] = result.fieldByName("source");
		pagedata['pageinfo'] = pageInfoOffline;
		pagedata['userinfo'] = userInfoOffline;
		pagedata['title'] = result.fieldByName("title");
		pagedata['bookmark'] = "";
		
		outputPageData(pagedata, pagediv);
	
	}else{

		addDebug("Page does not exist: "+pagenum);
		var pagedata = new Array();
        pagedata['source'] = "<div class='warning'>" +
						"<p><strong>Sorry, this page can not be found within the local database.</strong><br />This means it has either not been downloaded, or it does not exist yet.<br />When you go back online, you can write it yourself :)</p></div>";
        pagedata['pageinfo'] = pageInfoOffline;
        pagedata['userinfo'] = userInfoOffline;
        pagedata['title'] = "404: Page does not exist";
        pagedata['bookmark'] = "";

		outputPageData(pagedata, pagediv);
	}
	
	result.close();
}




function setStatus(status){

	if (document.getElementById("gearsStatus").innerHTML != status){
		document.getElementById("gearsStatus").innerHTML = status;
		addDebug("--("+status+")--");
	}
}


function setOnline(){

	if (isOffline){
		document.getElementById("userinfo").innerHTML = remember['userinfo'];
		document.getElementById("pageinfo").innerHTML = remember['pageinfo'];
	}
	isOffline = false;
	addDebug("Gears Online");
	setStatus(onlineStatus);
}


function setOffline(){

	isOffline = true;
	addDebug("Gears Offline (!!!)");
	setStatus(offlineStatus);
	
	document.getElementById("userinfo").innerHTML = userInfoOffline;
	document.getElementById("pageinfo").innerHTML = pageInfoOffline;
}

