GanjaGears.Versions = function( postId, postCode )
{
	this.postVersionId = 0;
	this.postVersions = [];
	this.currentVersion = -1;
	this.postId = postId;
	this.postCode = postCode;
	this.setVersionData();
	this.renderVersions();
	this.checkContentChanges = true;
	this.isContentChanged();
	var obj = this;
	var saveHandler = function( e )
	{
		if( obj && obj.currentVersion == -1 )
		{
			obj.saveVersion()
		}
	};
	this.saveHandler = saveHandler.bindAsEventListener( this ); 
	$( 'savebutton' ).observe( 'click', this.saveHandler );
}

GanjaGears.Versions.formExceptions = [];
GanjaGears.Versions.infoImg = '';

GanjaGears.Versions.prototype.setVersionData = function()
{
	GanjaGears.Tools.debug( 'Setting post version data' );
	this.postVersions = this.getVersions();
	this.postVersionId = this.postVersions.length;
	this.currentVersion = this.postVersions.length - 1;
}

GanjaGears.Versions.enable = function()
{
	GanjaGears.runningApp.setSetting( 'postVersioning', 1 );
	GanjaGears.runningVersions = new GanjaGears.Versions( GanjaGears.runningApp.postId, GanjaGears.runningApp.postCode ); 
	return GanjaGears.runningVersions;
}

GanjaGears.Versions.disable = function()
{
	GanjaGears.runningApp.setSetting( 'postVersioning', 0 );
	if( GanjaGears.runningVersions )
	{
		GanjaGears.runningVersions.turnOff();
		GanjaGears.runningVersions = null;
	}
	$( 'versionBox' ).innerHTML = '<a href="#" onclick="GanjaGears.Versions.enable();return false;">enable revision control</a>';
	$( 'versionBox' ).style.display = 'block';
}

GanjaGears.Versions.prototype.getVersions = function()
{
	GanjaGears.Tools.debug( 'Retrieving versions from DB' );
	var db = GanjaGears.DB.getDB();
	var re = db.execute( 'SELECT * FROM savedForms WHERE code LIKE ? ORDER BY code', [this.postCode + '#%'] );
	var ret = [];
	var versionRegex = /\#([0-9]+)$/;
	while( re.isValidRow() )
	{
		var data = null;
		try
		{
			data = eval( '(' + re.fieldByName( 'json' ) + ')' );
		}
		catch( ex )
		{
			GanjaGears.Tools.debug( 'Invalid JSON in line: ' + re.fieldByName( 'code' ), 1 );
			re.next();
			continue;
		}
		var line = {
			version : versionRegex.exec( re.fieldByName( 'code' ) )[1],
			date : re.fieldByName( 'date' ),
			json : data
		};
		ret.push( line );
		re.next();
	}
	return ret;
}

GanjaGears.Versions.prototype.renderVersions = function()
{
	GanjaGears.Tools.debug( 'Rendering versions list, it will be ' + this.postVersions.length + ' item long' );
	var items = [];
	for( var i = this.postVersions.length - 1; i >= 0 ; i-- )
	{
		items.push( '<a href="#" onclick="GanjaGears.runningVersions.loadVersion( ' + i + ' ); return false;">' + this.getVersionName( i ) + '</a> (' + this.postVersions[i].date + ')' );
	}
	var iHTML = '<p><img src="' + GanjaGears.Versions.infoImg + '" title="The revision control information is stored locally, inside the browser. It\'s not available to other users on other computers." /> <b>Current version:</b> <span id="currentVersionLabel"></span></p><p style="overflow: auto; height: 50px;">' + items.join( ', ' ) + '</p>';
	iHTML += '<a href="#" onclick="GanjaGears.runningVersions.saveVersion();return false;">save a new version now</a>';
	iHTML += ' <a href="#" onclick="GanjaGears.Versions.disable( GanjaGears.runningVersions ); return false;">disable revision control</a>';
	$( 'versionBox' ).innerHTML = iHTML;
	$( 'versionBox' ).style.display = 'block';
	this.setCurrentVersion( this.currentVersion );
}

GanjaGears.Versions.prototype.loadVersion = function( version )
{
	GanjaGears.Tools.debug( 'Loading version No' + version );
	if( this.currentVersion == -1 ) this.saveVersion();
	GanjaGears.Tools.loadFormData( GanjaGears.App.postFormId, this.postVersions[version].json, GanjaGears.Versions.formExceptions );
	this.setCurrentVersion( version );
}

GanjaGears.Versions.prototype.saveVersion = function()
{
	var versionId = this.postVersionId + '';
	while( versionId.length < 3 ) versionId = '0' + versionId;
	GanjaGears.Tools.debug( 'Saving a new version with code ' + this.postCode + '#' + versionId );
	GanjaGears.Tools.saveForm( GanjaGears.App.postFormId, this.postCode + '#' + versionId );
	this.setCurrentVersion( this.postVersionId );
	this.setVersionData();
	this.renderVersions();
}

GanjaGears.Versions.prototype.setCurrentVersion = function( version )
{
	this.currentVersion = version;
	$( 'currentVersionLabel' ).innerHTML = this.getVersionName( version );
}

GanjaGears.Versions.prototype.getVersionName = function( version )
{
		var text = 'Original version';
		if( version == -1)
		{
			if( this.postVersions && this.postVersions.length > 0 ) text = 'Not saved in your browser yet';
			else text = 'This post is not under local revision control yet';
		}
		else if( version )
		{
			if( version == 1 ) text = '1st';
			else if( version == 2 ) text = '2nd';
			else if( version == 3 ) text = '3rd';
			else text = version + 'th';
			text += ' modification';
		}
		return text;
}

GanjaGears.Versions.prototype.isContentChanged = function()
{
	if( !this.checkContentChanges ) return false;
	if( this.currentVersion != -1 )
	{
		//GanjaGears.Tools.debug( 'Checking if current post is still identical with the saved version' );
		var saved = this.postVersions[this.currentVersion].json;
		var current = GanjaGears.Tools.gatherFormData( GanjaGears.App.postFormId, GanjaGears.Versions.formExceptions );
		var identical = true;
		for( var item in saved )
		{
			if( GanjaGears.Versions.formExceptions.indexOf( item ) != -1 ) continue;
			if( current[item] == null )
			{
				GanjaGears.Tools.debug( item + ' is missing from the current version' );
				identical = false;
			}
			else if( current[item] != saved[item] )
			{
				GanjaGears.Tools.debug( item + ' is different in the current version' );
				GanjaGears.Tools.debug( 'Saved: ' + saved[item] );
				GanjaGears.Tools.debug( 'Current: ' + current[item] );
				identical = false;
			} 
		}
		for( var item in current )
		{
			if( GanjaGears.Versions.formExceptions.indexOf( item ) != -1 ) continue;
			if( saved[item] == null )
			{
				GanjaGears.Tools.debug( item + ' is missing from the saved version' );
				identical = false;
			}
		}
		if( !identical )
		{
			this.setCurrentVersion( -1 );
			//GanjaGears.Tools.debug( 'Nope' );
		}
		//else GanjaGears.Tools.debug( 'Yes' );
	}
	var obj = this;
	setTimeout( function() { obj.isContentChanged() }, 1000 );
}

GanjaGears.Versions.prototype.turnOff = function()
{
	this.postCode = '';
	this.postId = 0;
	this.postVersionId = 0;
	this.postVersions = [];
	this.currentVersion = -1;
	this.checkContentChanges = false;
	$( 'savebutton' ).stopObserving( 'click', this.saveHandler );
}