var Tags = Class.create({	
	
	initialize: function() 
	{
		this.box = $$('.body .sidebar .box.tags').first();
		if (!this.box) return;
		
		this.field = this.box.select('input[name=tag]').first();
		this.submit = this.box.select('input[name=submit]').first();
		this.container = this.box.select('.rows').first();
		
		this.halt = false;
		
		if (this.submit && this.field)
		{
			this.submit.onclick = function(e) { 
				Event.stop(e);
				this.add();
			}.bindAsEventListener(this);
			
			this.field.onkeyup = function(e) {
				var keycode = e.charCode || e.keyCode;
				var keypress = String.fromCharCode(keycode);
				if (keycode == 13 || keycode == 10 || keycode == 3)
				{
					this.add();
				}
			}.bindAsEventListener(this);		
		}
		
		this.initTags();
	},
	
	initTags: function()
	{
		var effects = [];
		
		this.box.select('.row').each(function(x) {
			var id = x.id.substr(3);
			var del = x.select('.delete a').first();
			
			if (del)
			{
				del.onclick = function(e) { 
					Event.stop(e);
					this.del(id);
				}.bindAsEventListener(this);
			}
			
			if (!x.visible()) effects.push(new Effect.Appear(x));			
		}.bind(this));
		
		new Effect.Parallel(effects, {});		
	},
	
	add: function()
	{
		if (!this.field.value.strip()) return;		
		
		if (this.halt) return;
		this.halt = true;
		this.field.disabled = true;
		
		app.blockLoad('tags', this.container, location.href, { 
				parameters: { 
					tags: this.field.value,
					process: 'addTags' 
				},
				
				callback: function() {
					this.halt = false;
					this.field.disabled = false;
					
					this.field.value = '';
					this.initTags();
				}.bind(this),
				
				errorCallback: function() {
					this.halt = false;
					this.field.disabled = false;					
				}.bind(this)
			});
	},
	
	del: function(id)
	{
		if (this.halt) return;
		
		new Effect.Fade('tag'+id, { afterFinish: function() { $('tag'+id).remove() } });
		new Ajax.Request(location.href,
			{
				method: 'get', 
				parameters: { 
					id: id,
					process: 'delTag'
				}
			});
	}
});

var Article = Class.create({	
	
	initialize: function() 
	{
		this.loading = $('loading');		
		this.halt = {};
		this.initSizes();	
		this.contents = new Article.contents($$('#article .contents').first(), { button: 'contentsChooser' });
	},
	
	initSizes: function()
	{
		var div = $$('#article .body .text');
		if (!div || !div[0]) return;
		var text = div[0];
		
		var setFontSize = function(size) {
			switch(size)
			{
				case 'fontSizeLarge':
					text.className = 'text large';
					Cookie.set('setting_fontsize', 2, 10);
					break;
				case 'fontSizeMedium':
					text.className = 'text medium';
					Cookie.set('setting_fontsize', 1, 10);										
					break;
				case 'fontSizeSmall':
					text.className = 'text small';
					Cookie.set('setting_fontsize', 0, 10);															
					break;
			}
		}

		$$('#article .textSize a').each(function(x) {
			if (x.hasClassName('on')) {
				this.fontButton = x;
				setFontSize(x.id);
			}
			
			$(x.id).onclick = function(e) {
				Event.stop(e);
				var element = Event.element(e);
				if (element.hasClassName('on')) return;
				
				element.addClassName('on');
				if (this.fontButton)
					this.fontButton.removeClassName('on');
				this.fontButton = element;
				
				setFontSize(element.id);
			}.bindAsEventListener(this);
						
		}.bind(this));

	},
	
	contact: function()
	{
		Position.clone($$('.contactSponsor').first(), this.loading);
		this.loading.show();
	},
	
	videos: function(videos)
	{
		if (!videos) return;
		
		videos.keys().each(function(id) { 
			var span = $('player'+id);
			
			var video = new Hash(videos.get(id));
			if (span && video.get('pid')) new Video(span, video.get('pid'), video.get('w'), video.get('h')); 
		}.bind(this));
	},
	
	vimeos: function(vimeos)
	{
		if (!vimeos) return;
		
		vimeos.each(function(id) { 
			var span = $('vimeo'+id);			
			new Vimeo(span, id);
		}.bind(this));
	}		
	
});


Article.contents = Class.create(Panel, {
	
	jump: function(e, element, index)
	{
		Event.stop(e);

		this.close();
		var elements = $$('.body .text '+element+':not('+element+'.annotateTitle)');
		if (elements && elements.length && elements[index])
			Effect.ScrollTo(elements[index]);
	}		
	
});

Panel.annotate = Class.create(Panel, {
	
	onInit: function(panel, options)
	{	
		this.options = options || {};
		this.closeLink = this.panel.select('a').first();
		this.addButton = $('annotateAdd');
		
		this.closeLink.onclick = function(e) {
			Event.stop(e);
			this.close();
		}.bindAsEventListener(this)

		this.addButton.onclick = function(e) {
			Event.stop(e);
			this.annotate();
		}.bindAsEventListener(this)

		Event.observe(document, 'mouseup', function(e) { 
			if (Event.element(e).id != 'annotateAdd')
				if (this.addButton.visible())
					this.cancel();
		}.bindAsEventListener(this));	

		$$('#article .body .text p', '#article .body .text h6').each(function(x) { x.observe('mouseup', function(e) {

			if (window.getSelection) {
				this.selection = window.getSelection();
			}
			else if (document.selection) {
				this.selection = document.selection.createRange();
			}
			else return;

			var selectedText = this.selection.toString ? this.selection.toString() : this.selection.text;

			if (selectedText)
			{
				Event.stop(e);
				this.addButton.show();
				this.button.hide();	
			}

		}.bindAsEventListener(this)) }.bind(this));
	},
	
	cancel: function()
	{
		if (this.selection && this.selection.empty)
			this.selection.empty();		
		this.addButton.hide();
		this.button.show();										
	},
	
	annotate: function()
	{		
		var newMarker = $('newMarker').firstDescendant().cloneNode(true);					
		var newAnnotation = $('newAnnotation').firstDescendant().cloneNode(true);			
		
		var range = this.getRangeObject();			
		range.collapse(false);
		
		if (range.insertNode) {
			range.insertNode(newMarker);	
		} else if (range.pasteHTML) {
			range.pasteHTML('<span id="_tmp_ie"></span>');
			range.parentElement().insertBefore(newMarker, $('_tmp_ie'));
			$('_tmp_ie').remove();
		}
		else return;

		this.cancel();

		$('annotations').appendChild(newAnnotation);

		var id = newMarker.identify();
		newMarker.id = 'marker'+id;
		newAnnotation.id = 'annotation'+id;
		
		var annotation = new Annotation(id);
		annotation.open();
	},
	
	getRangeObject: function()
	{
		if (Prototype.Browser.IE) return this.selection;
		if (this.selection.getRangeAt)
			return this.selection.getRangeAt(0);
		else {
			var range = document.createRange();
			range.setStart(this.selection.anchorNode, this.selection.anchorOffset);
			range.setEnd(this.selection.focusNode, this.selection.focusOffset);
			return range;
		}
	}	
});

var Annotation = Class.create({

	initialize: function(id)
	{
		if (!id) return;
		
		this.marker = $('marker'+id);
		if (!this.marker) return;

		this.annotation = $('annotation'+id);
		if (!this.annotation) return;

		this.loading = $('loading');
		this.halt = {};	
		
		this.annotation.setStyle({visibility: 'hidden', display: 'block'});
		if (this.annotation.getHeight() > 386) this.annotation.addClassName('long');	
		this.annotation.setStyle({visibility: '', display: 'none'});

		this.markup = this.marker.select('span.markup').first();			

		this.inner = this.annotation.select('.annotations').first();
		this.container = this.annotation.select('.annotations .container').first();	
		this.comments = this.annotation.select('.annotations .container div');
		
		this.textarea = this.annotation.select('textarea').first();
		this.article_id = this.annotation.select('input[name=article_id]').first();
		this.revision_id = this.annotation.select('input[name=revision_id]').first();
		this.topic_id = this.annotation.select('input[name=topic_id]').first();
		
		this.article = $$('#article .body .text').first();
		
		this.annotation.select('.close a').first().onclick = function(e) {
			Event.stop(e);
			this.close();
		}.bindAsEventListener(this);
		
		this.annotation.select('.submit input').first().onclick = function(e) {
			Event.stop(e);
			this.submit();
		}.bindAsEventListener(this);
				
		this.bubble = this.marker.select('a.bullet').first();
		this.bubble.onmouseover = this.bubble.onclick = function(e) {
			Event.stop(e);
			this.open();
		}.bindAsEventListener(this);		
		
		this.textarea.onfocus = function() { 
			app.clearOnFocus(this.textarea); 
			this.up();
			this.textarea.onfocus = this.up.bind(this);
		}.bind(this);		
	},
	
	refresh: function()
	{
		if (!this.annotation) return;
		if (!this.marker) return;
		
		if (this.annotation.getHeight() > 386)
		{
			new Effect.Parallel([
					new Effect.Morph(this.annotation, { style: { height: '386px' }, sync: true }),
					new Effect.Morph(this.inner, { style: { height: '335px' }, sync: true })					
				], {});
		}				
		this.comments = this.annotation.select('.annotations .container div');
		this.inner = this.annotation.select('.annotations').first();
		this.annotation.setStyle({ zIndex: 2 });

		this.blur();
	},
	
	blur: function()
	{	
		if (this.textarea.hasClassName('active'))
		{
			this.textarea.removeClassName('active');
			this.textarea.value = this.textarea.defaultValue;

			this.textarea.onfocus = function() { 
				app.clearOnFocus(this.textarea); 
				this.up();
				this.textarea.onfocus = this.up.bind(this);
			}.bind(this);
		}		
	},
	
	up: function()
	{
		this.annotation.setStyle({ zIndex: parseInt(this.annotation.getStyle('zIndex'), 10) + 1 });						
	},
	
	open: function()
	{
		if (this.halt.open) return;
		this.halt.open = true;

		this.blur();

		Position.clone(this.marker, this.annotation, {setWidth: false, setHeight: false});	
		if (parseInt(this.annotation.getStyle('left'), 10) > 650)
		{
			this.direction = 'top-right';
			this.annotation.addClassName('flip');
		}
		else
		{
			this.direction = 'top-left';			
			this.annotation.removeClassName('flip');			
		}

		if (Prototype.Browser.Opera)
		{
			this.annotation.show();
			return;
		}
				
		setTimeout(function() {
			Effect.Grow(this.annotation, { direction: this.direction, duration: 0.2 });
		}.bind(this), 100);
	},
	
	close: function()
	{
		if (!this.halt.open || this.halt.submit) return;
		
		Effect.Shrink(this.annotation, { direction: this.direction, duration: 0.2, afterFinish: function() {
			this.halt.open = false;
			if (!this.comments.length)
			{
				this.annotation.remove();
				this.marker.remove();				
			}

		}.bind(this) });		
	},
	
	callback: function(json)
	{
		this.blur();		
		
		if (json.comment_id && $('commentId'+json.comment_id))
		{
			new Effect.Appear('commentId'+json.comment_id, { afterFinish: function() {
				this.refresh();				
			}.bind(this) });
		}
		if (json.topic_id)
		{
			this.topic_id.value = json.topic_id;
			this.markup.update('[ANNOTATION='+json.topic_id+']');
		}
	},
	
	submit: function()
	{
		var value = this.textarea.value.strip();
		if (!value || value == this.textarea.defaultValue || !this.article_id.value)
		{
			new Effect.Highlight(this.textarea);
			return;
		}		

		if (this.halt.submit) return;
		this.halt.submit = true;
		
		var parameters = { comment: value, topicName: 'annotation' };
		var url = this.topic_id.value ? '/comment/topic/'+this.topic_id.value+'/' : '/comment/annotations/'+this.article_id.value+'/';

		if (!this.topic_id.value) 
		{
			parameters.article = this.article.innerHTML;
			parameters.spanid = this.marker.id;
			parameters.revision_id = this.revision_id.value;
		}

		Position.clone(this.textarea, this.loading);
		
		app.blockLoad('annotation', this.container, url, { 
				insertion: 'bottom',
				parameters: parameters,				
				callback: this.callback.bind(this),
				commonCallback: function() { this.halt.submit = false; }.bind(this),
				loading: this.loading
			});		
	}
});

window.windowOnload.push(function() {	
	window.tags = new Tags();
	window.article = new Article();	
	window.bookmark = new Toggle('article', 'bookmark');
	window.recommend = new Toggle('article', 'recommend');	
	window.annotate = new Panel.annotate('annotate');
});
