/**
 * @author Vladimir Cvetic over @ ferdinand.rs
 * @version 0.20
 * @date 22.12.2008
 * @requirements Prototype >= 1.6.0.3 && Scriptaculous >= 1.8.2
 * @url http://ferdinand.rs/javascript/
**/
if (window.Ferdinand == undefined) Ferdinand = Class.create({});
Ferdinand.PhotoTag = Class.create({
	
	initialize: function(element, options){
		element = $( element );
		this.element = element;	
		
		this.tags = Array();
		this.tags_link = Array();
		
		this.options = Object.extend({
				sqsize: '15%',
				sqclass: 'square-class',
				tagInputClass: 'tag-input',
				tag_square_class: 'tag_square_class',
				tag_class: 'tag_class',
				remove_link_class: 'remove_link_class',
				square_zindex: 3,
				tag_input_zindex: 4,
				tag_zindex: 2,
				lang: {
					add: 'Add',
					remove: 'Close'
				},
				add_tag: '/social/js/phototag/php/add_tag.php',
				get_tags: '/social/js/phototag/php/get_tags.php',
				remove_tag: '/social/js/phototag/php/remove_tag.php',
				tag_ref_container: 'tag_ref_container',
				ref_ul_class: 'ref_ul_class'
			}, options || {});
		
		this.pos = this.element.positionedOffset();
		Event.observe(document.onresize ? document : window, 'resize', function(){
			this.pos = this.element.positionedOffset();
			this.getTags();
		}.bind(this)); 
		
		if (this.element.complete) {
			this.init();
		} else {
			this.element.observe('load', function(){
				 this.init();
			}.bind(this));				
		}
	},
	
	init: function (){
			this.dimensionsMode();
			if (this.mode=='%') {
				this.square_size = this.element.getWidth() * this.options.sqsize/100;
			} else {
				this.square_size = this.options.sqsize;
			}
			this.ptid = this.element.readAttribute('ptid');
			this.createTooltip();
			this.createTagInputBox();
			this.setEvent();
			this.getTags();	
	},	
	
	setEvent: function () {
		Event.observe(this.element, 'click', function(event){
			this.setSquare(event);
		}.bind(this));
	},
	
	setSquare: function(event) {
		
		if (this.square_exists=='Y') {
			this.removeSquare();
		}
		mouseX = Event.pointerX(event);
		mouseY = Event.pointerY(event);	
		
		this.mouse = Class.create({});
		this.mouse.x = mouseX;
		this.mouse.y = mouseY;
		this.square_coord = Class.create({});

		this.square_coord.top = mouseY - this.square_size/2;
		this.square_coord.left = mouseX - this.square_size/2;
		
		this.square = new Element('div', {className: this.options.sqclass}).setStyle({
				position: 'absolute',
				width: this.square_size+'px',
				height: this.square_size+'px',
				top: this.square_coord.top+'px',
				left: this.square_coord.left+'px',
				zIndex: this.options.square_zindex
			});
		document.body.appendChild(this.square);				
		this.showTagInputBox();
		this.square_exists = 'Y';
		Event.observe(document, 'keypress', function(e){
			var code;
			if (!e) var e = window.event;
			if (e.keyCode) code = e.keyCode;
			else if (e.which) code = e.which;
			switch (code) {
				case 27:
					this.removeSquare();
				break;
			}
		}.bind(this));
	},
	
	removeSquare: function () {
		this.square.remove();
		this.input_box.value = '';
		this.tag_input.hide();
		$(document).stopObserving('keypress');
		this.tag_input.stopObserving('keypress');
		this.square_exists = 'N';
	},
	
	createTagInputBox: function () {		
		this.tag_input = new Element('div', {className: this.options.tagInputClass}).hide();
		document.body.appendChild(this.tag_input);		

		this.inner_span = new Element('span');
		this.tag_input.appendChild(this.inner_span);
				
		this.inner_div = new Element('div');
		this.tag_input.appendChild(this.inner_div);		
		
		this.inner_p = new Element('p');
		this.inner_div.appendChild(this.inner_p);			
		
		this.input_box = new Element('input', {'type': 'text'});
		this.inner_p.appendChild(this.input_box);
		
		this.tag_button = new Element('button').update(this.options.lang.add);
		this.inner_p.appendChild(this.tag_button);
				
		this.tag_button_rem = new Element('button').update(this.options.lang.remove);
		this.inner_p.appendChild(this.tag_button_rem);

		
		this.submitEvents();
	},

	showTagInputBox: function () {
		this.tag_input.setStyle({
				position: 'absolute',
				top: this.square_coord.top+this.square_size+'px',
				left: this.square_coord.left+this.square_size-20+'px',
				zIndex: this.options.tag_input_zindex
		}).show();
		this.input_box.focus();
		Event.observe(this.tag_input, 'keypress', function(e){
			var code;
			if (!e) var e = window.event;
			if (e.keyCode) code = e.keyCode;
			else if (e.which) code = e.which;
			switch (code) {
				case 13:
					this.submitTag();
				break;
			}
		}.bind(this));
	},
	
	submitTag: function () {
		var vars = new Hash();
		vars.set('x', this.mouse.x - this.pos.left);
		vars.set('y', this.mouse.y - this.pos.top);
		vars.set('tag', this.input_box.value);
		vars.set('ptid', this.ptid);
		
		new Ajax.Request(this.options.add_tag, {
		  method: 'post',
		  parameters: vars,
		  onSuccess: function(t) {
		  	this.removeSquare();
		  	tags = t.responseText.evalJSON(true);
			this.showTags(tags);
		  }.bind(this)
		});
	},
	
	getTags: function() {
		var vars = new Hash();
		vars.set('ptid', this.ptid);
		
		new Ajax.Request(this.options.get_tags, {
		  method: 'post',
		  parameters: vars,
		  onSuccess: function(t) {
		  	tags = t.responseText.evalJSON(true);
			this.showTags(tags);
		  }.bind(this)
		});		
	},
	
	showTags: function(tags) {
		
		this.removeTags();
		
		tags.each(function(item){
			var item = item;

			topc = parseInt(item.y)+this.pos.top-this.square_size/2;
			leftc = parseInt(item.x)+this.pos.left-this.square_size/2;		
						
			this.tags[item.id] = new Element('div', {className: this.options.tag_square_class, id: 'tag-'+item.id});
			
			this.tags[item.id].setStyle({
				position:'absolute',
				width: this.square_size+'px',
				height: this.square_size+'px',
				top: topc+'px',
				left: leftc+'px',
				zIndex: this.options.tag_zindex,
				backgroundImage: 'url(0)'
			});
			
			this.tags[item.id].observe('mouseover', function() {
				this.showTooltip(item);
			}.bind(this));
			
			this.tags[item.id].observe('mouseout', function() {
				this.hideTooltip();
			}.bind(this));
			document.body.appendChild(this.tags[item.id]);
			
							
		}.bind(this));
		this.showTagRefs(tags);
	},
	
	removeTags: function () {
		
		this.tags.each(function(tag){
			if (tag) {
				tag.remove();
			}
		});
		this.tags = Array();
	},
	
	showTagRefs: function (tags)
	{
		if (!$( this.options.tag_ref_container )) return false;
		
		
		$( this.options.tag_ref_container ).setStyle({width:this.element.getWidth()+'px'});
		this.refs = Array();
		this.refs_dele = Array();
		this.refli = Array();
		this.ref_ul = new Element('ul', {className: this.options.ref_ul_class});
		
		tags.each(function(item){
			var item = item;

			this.refli[item.id] = new Element('li');
			this.ref_ul.appendChild(this.refli[item.id]);
			
			this.refs[item.id] = new Element('a', {id: 'tagref-'+item.id, href: "#"}).update(item.tag);
			this.refli[item.id].appendChild(this.refs[item.id]);
			
			this.refli[item.id].innerHTML += '&nbsp;';
						
			this.refs_dele[item.id] = new Element('a', {id: 'tagrefdele-'+item.id, href: "#"}).update('(x)');
			this.refli[item.id].appendChild(this.refs_dele[item.id]);
			
			this.refs_dele[item.id].observe('click', function() {
				this.hideTooltip();
				this.removeTag(item);
			}.bind(this));			
			this.refli[item.id].observe('mouseover', function() {
				this.showTooltip(item);
			}.bind(this));
			this.refli[item.id].observe('mouseout', function() {
				this.hideTooltip();
			}.bind(this));
									
		}.bind(this));
		$( this.options.tag_ref_container ).update(this.ref_ul);
	},
	
	removeTag: function (item) {
		var vars = new Hash();
		vars.set('id', item.id);
		
		new Ajax.Request(this.options.remove_tag, {
		  method: 'post',
		  parameters: vars,
		  onSuccess: function(t) {
		  	tags = t.responseText.evalJSON(true);
			this.showTags(tags);		
		  }.bind(this)
		});		
	},
	
	createTooltip: function () {
		this.tooltip = new Element('div', {className: this.options.tag_class}).hide();
		this.tooltip.setStyle({
				position:'absolute',
				zIndex: this.options.tag_zindex+1
		});
		document.body.appendChild(this.tooltip);
		this.tooltip.observe('mouseout', function() {
			this.hideTooltip();
		}.bind(this));
	},
	
	showTooltip: function (item) {
		this.tooltip.stopObserving('mouseover');
		this.tooltip.observe('mouseover', function() {
			this.showTooltip(item);
		}.bind(this));		
		this.tooltip.update(item.tag);
		this.tooltip.style.top = (parseInt(item.y)+this.pos.top)+'px';
		this.tooltip.style.left = (parseInt(item.x)+this.pos.left)+'px';
		this.tooltip.show();
	},
	
	hideTooltip: function ()
	{
		this.tooltip.hide();
	},
	
	submitEvents: function () {
		this.tag_button.observe('click', function(event){
			this.submitTag();
		}.bind(this));
		this.tag_button_rem.observe('click', function(event){
			this.removeSquare();
		}.bind(this));
	},
	
	dimensionsMode: function () {
		if (this.options.sqsize.endsWith('%')) {
			this.mode = '%';
		} else {
			this.mode = 'px';
		}
		this.options.sqsize = this.options.sqsize.sub(this.mode, '', 1);
		
	}
	
});