GanjaGears.Tags = function( siteId )
{
	this.enabled = true;
	this.siteId = siteId;
	this.cCont = null;
	this.tagContainer = $( 'tags' );
	this.displayed = false;
	this.oldTagStr = this.tagContainer.value;
	this.oldTags = this.getTagTokens( this.tagContainer.value );
	GanjaGears.tagManager = this;
	if( !GanjaGears.Tools.checkGears() )
	{
		return false;
	}
	this.init();
}

GanjaGears.Tags.workerUrl = '';

GanjaGears.Tags.prototype.init = function()
{
	GanjaGears.Tools.debug( 'Initializing autocompletion' );
	var db = GanjaGears.DB.getDB();
	var re = db.execute( 'SELECT checkDate FROM tagCheckLog WHERE siteId = ? ORDER BY checkDate DESC', [this.siteId] );
	var needUpdate = true;
	if( re.isValidRow() )
	{
		var checkDate = GanjaGears.Tools.getDate( re.fieldByName( 'checkDate' ) );
		var curDate = new Date();
		if( curDate.getTime() - checkDate.getTime() < 7200000 ) needUpdate = false;
	}
	if( needUpdate ) this.initTagLoad();
	var obj = this;
	
	Event.observe( this.tagContainer, 'keyup', function( e ) { obj.tagsChanged( e ); } );
}

GanjaGears.Tags.prototype.initTagLoad = function()
{
	GanjaGears.Tools.debug( 'Looking for new tags' );
	var obj = this;
	var options = {
		'parameters'	:
		{
			'op'		: 'admin_tags',
			'siteId'	: this.siteId
		},
		'onComplete'	: function( resp ) { obj.loadTags( resp ); }
	};
	new Ajax.Request( '/ged/', options );
	GanjaGears.Tools.debug( 'Downloading tags for site' );
}

GanjaGears.Tags.prototype.loadTags = function( resp )
{
	var data = null;
	try
	{
		data = eval( '(' + resp.responseText + ')' );
	}
	catch( ex )
	{
		
	}
	GanjaGears.Tools.debug( 'Tags downloaded' );
	if( data != null )
	{
		var workerPool = google.gears.factory.create( 'beta.workerpool' );
		var obj = this;
		var db = GanjaGears.DB.getDB();
		db.close();
		GanjaGears.DB.unsetDB();
		var message = {
			'action': 'loadTags',
			'dbName': GanjaGears.DB.dbName,
			'tags' : data,
			'siteId' : this.siteId
		};
		workerPool.onmessage = function( a, b, msg ) {	obj.workerMessage( msg ); }
		var childWorkerId = workerPool.createWorkerFromUrl( GanjaGears.Tags.workerUrl );
		workerPool.sendMessage( message, childWorkerId );
		GanjaGears.Tools.debug( 'Tags sent to worker' );
		/*this.tagPool = data;
		var db = GanjaGears.DB.getDB();
		db.execute( 'DELETE FROM tags WHERE siteId = ?', [this.siteId] );
		GanjaGears.Tools.debug( 'Old tags removed' );
		for( var i = 0; i < data.length; i++ ) db.execute( 'INSERT INTO tags (tag, siteId) VALUES (?,?)', [data[i], this.siteId] );
		GanjaGears.Tools.debug( data.length + ' tags inserted' );		
		db.execute( 'INSERT INTO tagCheckLog (siteId) VALUES (?)', [this.siteId] );
		this.processPool();
		GanjaGears.Tools.debug( 'Tag replacement has been started' );*/
	}
}

GanjaGears.Tags.prototype.workerMessage = function( message )
{
	if( message.body.msg ) GanjaGears.Tools.debug( message.body.action + ' worker message: ' + message.body.msg );
	else GanjaGears.Tools.debug( 'Worker report: ' + message.body.action + ( message.body.success ? ' was successful' : ' failed' ) );
}

/*GanjaGears.Tags.prototype.processPool = function()
{
	var pool = [];
	var sqlPart = [];
	for( var i = 0; i < 100 && i < this.tagPool.length; i++ )
	{
		pool.push( this.tagPool.pop() );
		sqlPart.push( '?' );
	}
	
}*/

GanjaGears.Tags.prototype.tagsChanged = function( e )
{
	if( !this.enabled ) return false;
	var tagStr = e.target.value;
	if( this.oldTagStr == tagStr ) return false;
	this.oldTagStr = tagStr;
	if( !this.currentTag ) this.currentTag = '';
	this.tags = this.getTagTokens( tagStr );
	var diffTags = [];
	var diffTagPos = [];
	for( var i = 0; i < this.tags.length; i++ )
	{
		var oldPos = this.oldTags.indexOf( this.tags[i] ); 
		if (oldPos == -1)
		{
			diffTagPos.push( i );
			diffTags.push(this.tags[i]);
		}
		else this.oldTags.splice(oldPos, 1); 
	}
	this.oldTags = this.tags;
	if( diffTags.length == 0 ) return false;
	this.closeChoices();
	this.currentTag = diffTags[0];
	this.currentTagPos = diffTagPos[0];
	if( this.currentTag.length < 2 ) return false;
	var db = GanjaGears.DB.getDB();
	var re = db.execute( 'SELECT tag FROM tags WHERE siteId = ? AND tag LIKE ?', [this.siteId, this.currentTag + '%'] );
	this.choices = [];
	while( re.isValidRow() )
	{
		this.choices.push( re.fieldByName( 'tag' ) );
		re.next();
	}
	if( this.choices.length > 0 ) this.showTagChoices();
}

GanjaGears.Tags.prototype.getTagTokens = function( str )
{
	var tokens = str.split( '"' );
	var ret = [];
	var pushFunc = function( item )
	{
		item = item.strip();
		if( item.length == 0 ) return;
		ret.push( item );
	} 
	for( var i = 0; i < tokens.length; i++ )
	{
		var token = tokens[i].strip();
		if( token.length == 0 ) continue;
		if( i % 2 == 0 ) token.split( ' ' ).each( pushFunc );
		else ret.push( token );
	}
	return ret;
}

GanjaGears.Tags.prototype.showTagChoices = function()
{
	if( !this.enabled ) return false;
	var obj = this;
	if( !this.cCont )
	{
		this.cCont = new Element( 'ul', { 'class' : 'tagChoices' } );
		var bodies = document.getElementsByTagName( 'body' );
		var body = bodies[0];
		body.appendChild( this.cCont );
		Event.observe( window, 'keydown', function( e ) { obj.choiceKeyPressed( e ) } );
		Event.observe( window, 'click', function( e ) { if( !e.target.descendantOf( obj.cCont ) ) { obj.closeChoices(); } } );
		Event.observe( $( 'tags' ), 'blur', function( e ) { obj.closeChoices(); } );
		this.cCont.style.position = 'absolute';
	}
	this.cCont.innerHTML = '';
	var cOffset = this.tagContainer.cumulativeOffset();
	this.cCont.style.left = cOffset.left + 'px';
	this.cCont.style.top = ( cOffset.top + this.tagContainer.getHeight() ) + 'px';
	this.choicePos = 0;
	this.choiceItems = [];
	for( var i = 0; i < this.choices.length; i++ )
	{
		var choice = new Element( 'li', { 'class' : ( i == 0 ? 'selected' : '' ) } ).update( this.choices[i] );
		choice.pos = i;
		choice.observe( 'mouseover', function( e ) { obj.changePos( e.target.pos ) } );
		choice.observe( 'click', function( e ) { obj.selectChoice( e.target.pos ) } );
		this.cCont.appendChild( choice );
		this.choiceItems.push( choice );
	}
	this.displayed = true;
	this.cCont.style.display = 'block';
}

GanjaGears.Tags.prototype.choiceKeyPressed = function( e )
{
	var kc = e.keyCode;
	if( !this.displayed || [13,27,38,40].indexOf( kc ) == -1 ) return false;
	Event.stop( e );
	if( kc == 13 ) this.selectChoice( this.choicePos );
	else if( kc == 27 )
	{
		this.closeChoices();
	}
	else
	{
		var newPos = 0;
		if( kc == 40 )
		{
			if( this.choicePos == this.choices.length - 1 ) newPos = 0;
			else newPos = this.choicePos + 1; 
		}
		else if( kc == 38 )
		{
			if( this.choicePos == 0 ) newPos = ( this.choices.length - 1 );
			else newPos = this.choicePos - 1; 
		}
		this.changePos( newPos );
	}
}

GanjaGears.Tags.prototype.changePos = function( newPos )
{
	this.choiceItems[this.choicePos].removeClassName( 'selected' );
	this.choicePos = newPos;
	this.choiceItems[this.choicePos].addClassName( 'selected' );
}


GanjaGears.Tags.prototype.selectChoice = function( pos )
{
	if( !this.enabled ) return false;
	//this.tags.push( this.choices[pos] );
	var tags = [];
	var curTag = this.currentTag;
	var curTagPos = this.currentTagPos;
	var selectedTag = this.choices[pos];
	var quotify = function( item, pos )
	{
		var ret = item;
		if( item == curTag && curTagPos == pos ) ret = selectedTag;
		if( ret.indexOf( ' ' ) != -1 ) ret = '"' + ret + '"';
		
		tags.push( ret );
	}
	for( var i = 0; i < this.tags.length; i++ ) this.tags[i] = quotify( this.tags[i], i ); 
	this.tagContainer.value =  tags.join( ' ' );
	this.oldTagStr = this.tagContainer.value;
	this.oldTags = this.getTagTokens( this.tagContainer.value );
	this.closeChoices();
}

GanjaGears.Tags.prototype.closeChoices = function()
{
	if( this.cCont ) this.cCont.style.display = 'none';
	this.displayed = false;
}

GanjaGears.Tags.enable = function()
{
	GanjaGears.runningApp.setSetting( 'tagAutocomplete', 1 );
	GanjaGears.runningTags = new GanjaGears.Tags( $( 'siteId' ).value );
	$( 'tagAutocompleteIndicator' ).innerHTML = '<a href="#" onclick="GanjaGears.Tags.disable();return false;">Tag autocompletion is ON</a>';
	return GanjaGears.runningTags;
}

GanjaGears.Tags.disable = function()
{
	GanjaGears.runningApp.setSetting( 'tagAutocomplete', 0 );
	if( GanjaGears.runningTags ) GanjaGears.runningTags.enabled = false;
	GanjaGears.runningTags = null;
	$( 'tagAutocompleteIndicator' ).innerHTML = '<a href="#" onclick="GanjaGears.Tags.enable();return false;">Tag autocompletion is OFF</a>';
}
