///////////////////////////////////////////////////////////////////////////////
// console.log workaround

try { console.log('console.log() available'); } catch(e) { console = { log: function(){} } };

///////////////////////////////////////////////////////////////////////////////
// Common

var common = {
	lang: 'pt'
};

///////////////////////////////////////////////////////////////////////////////
// Localization

var words = {
	pt: {
		counter: new Template('<b>#{count}</b> de até #{max} caracteres'),
		counterRange: new Template('<b>#{count}</b> de #{min} a #{max} caracteres'),
		toClose: 'Fechar'
	},
	en: {
		counter: new Template('<b>#{count}</b> of #{max} characters'),
		counterRange: new Template('<b>#{count}</b> of #{min} to #{max} characters'),
		toClose: 'Close'
	},
	es: {
		counter: new Template('<b>#{count}</b> de #{max} caracteres'),
		counterRange: new Template('<b>#{count}</b> de #{min} a #{max} caracteres'),
		toClose: 'Cerrar'
	}
};

///////////////////////////////////////////////////////////////////////////////
// HTML e interface

var UI = {};

///////////////////////////////////////////////////////////////////////////////
// Properties

UI.ua = navigator.userAgent.toLowerCase();
UI.khtml = /khtml|safari|webkit/.test(UI.ua);
UI.opera = /opera/.test(UI.ua);

///////////////////////////////////////////////////////////////////////////////
// Create and return extended HTML Element

UI.create = function(str){
	return $(document.createElement(str));
};

///////////////////////////////////////////////////////////////////////////////
// Form methods

UI.forms = {
	
	// Exchange elements: hide one to show another
	exchange: function(hide, show){
		show = $(show);
		hide = $(hide);
		show.setStyle({ 'display':'block' });
		hide.setStyle({ 'display':'none' });
		UI.forms.enableGroup(show);
		UI.forms.disableGroup(hide);
		return false;
	},

	// Disable form elements in group
	disableGroup: function(el){
		$A(el.getElementsByTagName('input')).each(UI.forms.disable);
		$A(el.getElementsByTagName('select')).each(UI.forms.disable);
		$A(el.getElementsByTagName('textarea')).each(UI.forms.disable);
	},
	
	// Disable form element
	disable: function(el){
		el.disabled = true;
	},
	
	// Enable form elements in group
	enableGroup: function(el){
		$A(el.getElementsByTagName('input')).each(UI.forms.enable);
		$A(el.getElementsByTagName('select')).each(UI.forms.enable);
		$A(el.getElementsByTagName('textarea')).each(UI.forms.enable);
	},
	
	// Enable form element
	enable: function(el){
		el.disabled = false;
	}
};

///////////////////////////////////////////////////////////////////////////////
// Tabs

UI.tabs = Class.create();
UI.tabs.prototype = {
	
	initialize: function(as){
		this.contents = [];
		this.togglers = as;
		for(var i=0; i < this.togglers.length; i++){
			var a = $(this.togglers[i]);
			if(!a){
				break;
			}
			this.togglers[i] = a;
			this.verify(a);
		}
	},
	
	// Verify and associate content
	// to show when clicked on tab link
	verify: function(a){
		var _ = this;
		var hrf = a.href;
		if(hrf){
			var tt = hrf.substr(hrf.lastIndexOf('#') + 1);
			var c = $(tt);
			this.contents.push(c);
			a.setProperty('tabtarget', tt);
			if(!a.hasClassName('current')){
				c.setStyle({ 'display':'none' });
				UI.forms.disableGroup(c);
			}
			Event.observe(a, 'click', function(event){
				Event.stop(event);
				_.click(a, c);
			});
		}
	},
	
	// Reset tabs, set tab as current and show content
	click: function(a, c){
		this.reset();
		this.setTabs(a);
		//a.setProperty('class', 'current');
		c.setStyle({ 'display':'block' });
		UI.forms.enableGroup(c);
	},
	
	// Reset tabs
	reset: function(){
		for(var i=0; i < this.togglers.length; i++){
			var a = this.togglers[i];
			var c = this.contents[i];
			a.removeClassName('current');
			c.setStyle({ 'display':'none' });
			UI.forms.disableGroup(c);
		}
	},
	
	// Sets concurrent tabs (tabs that targets the same content)
	setTabs: function(a){
		var tt = a.readAttribute('tabtarget');
		var as = $$('a[tabtarget=' + tt + ']');
		as.each(this.setTab);
	},
	
	// Sets a tab current
	setTab: function(a){
		a.setProperty('class', 'current');
	}
};

///////////////////////////////////////////////////////////////////////////////
// Character counters

UI.counter = Class.create();
UI.counter.prototype = {

	initialize: function(field){
		this.field = $(field);
		if(!this.field){
			return false;
		}
		this.span = $(this.field.id + 'counter');
		this.max = this.field.readAttribute('maxlength');

		var min = this.field.readAttribute('minlength');
		if(min){
			this.min = min;
			this.template = words[common.lang].counterRange;
		} else {
			this.template = words[common.lang].counter;
		}
		
		Event.observe(this.field, 'keyup', this.update.bindAsEventListener(this));
		Event.observe(this.field, UI.keyCodeEvent, this.prevent.bindAsEventListener(this));
		this.update();
	},
	
	// Update counter
	update: function(){
		var count = this.field.value.length;
		var max = this.max;
		if(count > max){
			this.field.value = this.field.value.substr(0, max);
			count = this.field.value.length;
		}
		if(this.min){
			this.span.setHTML( this.template.evaluate({'count': count, 'min': this.min, 'max': max}) );
		} else {
			this.span.setHTML( this.template.evaluate({'count': count, 'max': max}) );
		}
	},
	
	// Prevent default events
	prevent: function(event){
		var count = this.field.value.length;
		var max = this.max;
		var event = event || window.event;
		if(count >= max){
			if(!UI.isEventKey(event.keyCode)){
				Event.stop(event);
			}
		}
	}
};

///////////////////////////////////////////////////////////////////////////////
// Convenience methods

UI.isFirst = function(el){
	return (el.previous() == undefined) ? true : false;
};

UI.isLast = function(el){
	return (el.next() == undefined) ? true : false;
};

///////////////////////////////////////////////////////////////////////////////
// Reorder menu

UI.reorder = Class.create();
UI.reorder.prototype = {

	initialize: function(str, upCallback, downCallback){
		this.colorStart = "#e2e8de";
		this.colorEnd = "#ffffff";
		this.upClass = 'subir';
		this.downClass = 'descer';
		this.firstClass = 'first';
		this.lastClass = 'last';
		this.overClass = 'over';
		var el = $(str);
		var spans = $$('#' + str + ' ul span');
		spans.each(this.initSpan.bindAsEventListener(this));
	},
	
	initSpan: function(span){
		var ref = span.parentNode.parentNode;
		var up = UI.create("a").setProperties({ 'href':'#', 'class':this.upClass, 'id':ref.id }).setHTML('Subir').injectBefore(span);
		var down = UI.create("a").setProperties({ 'href':'#', 'class':this.downClass, 'id':ref.id }).setHTML('Descer').injectBefore(span);
		Event.observe(up, 'click', this.upClick.bindAsEventListener(this));
		Event.observe(down, 'click', this.downClick.bindAsEventListener(this));
		this.check(ref);
	},
	
	check: function(el){
		var cl = "";
		var prev = el.previous();
		if(prev){
			var next = el.next();
			if(!next){
				cl = this.lastClass;
			}
		} else {
			cl = this.firstClass;
		}
		el.setProperty("class", cl);
	},
	
	upClick: function(event){
		Event.stop(event);
		var a = Event.element(event);
		var el = $(a.parentNode.parentNode);
		var id = a.id;
		var prev = el.previous();
		if(prev){
			el.injectBefore(prev);
			this.check(el);
			this.check(prev);
			this.blink(el);
			this.upCallback(id);
		}
	},
	
	downClick: function(event){
		Event.stop(event);
		var a = Event.element(event);
		var el = $(a.parentNode.parentNode);
		var id = a.id;
		var next = el.next();
		if(next){
			el.injectAfter(next);
			this.check(el);
			this.check(next);
			this.blink(el);
			this.downCallback(id);
		}
	},
	
	upCallback: function(id){
		increasePosition(id);
		//console.log('up' + id);
	},
	
	downCallback: function(id){
		decreasePosition(id);
		//console.log('down' + id);
	},
	
	blink: function(el){
		var span = el.down('span');
		new Effect.Highlight(span, { duration: 1, startcolor: this.colorStart, endcolor: this.colorEnd });
	}

};

///////////////////////////////////////////////////////////////////////////////
// Tree

UI.tree = Class.create();
UI.tree.prototype = {
	
	initialize: function(str, info){
		this.id = str;
		this.name = arguments[2] || '';
		this.build($(str), info);
		this.initEvents();
	},

	// Recursively builds tree
	build: function(el, info){
		var last = info.length - 1;
		for(var i=0, node; node=info[i]; i++)
		{
			var li  = UI.create('li').injectInside(el);
			var div = UI.create('div').injectInside(li);
			var tag;
			var tagCode = node.label;
			
			// Gives ID to node to use in reorder script
			if(node.value){
				li.setProperty('id', node.value);
			}
			
			// Does the node have a link?
			if(node.href || node.children){
				tag = UI.create('a').setProperty('href', node.href);
			} else {
				tag = UI.create('span');
			}
			
			// Does the node have a related checkbox?
			if(node.check){
				var nodeID = this.name + node.value;
				var checked = (node.checked) ? ' checked="checked"' : '';
				tagCode = [
					'<input type="checkbox" name="', this.name,
					'" value="', node.value,
					'" id="', nodeID, '"',
					checked, ' /> <label for="', nodeID, '">', node.label, '</label>'
				].join('');
			}
			
			// Inject node
			tag.setHTML(tagCode).injectInside(div);
			
			// Is the node currently selected?
			if(node.current){
				tag.addClassName('current');
			}
			
			// Is the node currently checked?
			if(node.checked){
				tag.addClassName('checked');
			}
			
			// Does the node contain children?
			if(node.children){
				tag.addClassName('toggler');
				var ul = UI.create('ul').injectInside(div);
				this.build(ul, node.children, this.name);
			}
			
			// Is it the last node?
			if(i == last){
				li.setProperty('class', 'last');
			}
		}
	},

	// Initialize events
	initEvents: function(){
		var a1 = $$('#' + this.id + ' .toggler');
		var a2 = $$('#' + this.id + ' .current', '#' + this.id + ' .checked');
		a1.each(this.verify.bindAsEventListener(this));
		a2.each(this.expand.bindAsEventListener(this));
	},
	
	// Adds event to togglers
	verify: function(a){
		Event.observe(a, 'click', this.toggle.bindAsEventListener(this));
	},
	
	// Click listener
	toggle: function(event){
		var a = Event.element(event);
		Event.stop(event);
		this._toggle(a);
	},
	
	// Toggles tree node
	_toggle: function(a){
		a.toggleClassName('minustoggler');
		a.next().toggleClassName('expanded');
	},
	
	// Toggles all nodes
	toggleAll:function(){
		var a1 = $$('#' + this.id + ' .toggler');
		a1.each(this._toggle.bindAsEventListener(this));
	},
	
	// Expands parent node until the root
	expand: function(a){
		if(!this.isRoot(a)){
			var toggler = a.up('ul').previous();
			if(!this.isToggled(toggler)){
				this._toggle(toggler);
				this.expand(toggler);
			}
		}
	},
	
	// Checks if link is at the tree's first level
	isRoot: function(a){
		return a.up('ul').id == this.id;
	},
	
	// Checks if toggler is toggled
	isToggled: function(a){
		return a.hasClassName('minustoggler');
	}
};

///////////////////////////////////////////////////////////////////////////////
// Togglers

UI.toggler = Class.create();
UI.toggler.prototype = {
	
	initialize: function(str){
		this.toggler = $(str);
		this.pane = this.toggler.next();
		this.pane.hide();
		Event.observe(this.toggler, 'click', this.toggle.bindAsEventListener(this));
	},
	
	toggle: function(){
		this.toggler.toggleClassName('current');
		this.pane.toggle();
	}
};

///////////////////////////////////////////////////////////////////////////////
// Thickbox 2.1
// Copyright (c) 2006, 2007 Cody Lindley (http://www.codylindley.com)
// Adapted to Prototype by Eduardo Omine / 2007

UI.box = {

	duration: 0.75,
	opacity: 0.75,
	titleHeight: 0,

	// Initialize links
	init: function(){
		var as = $$('a');
		as.each(UI.box.verify);
	},

	// Add event according to link's "rel" attribute
	verify: function(a){
		a = $(a);
		var rel = a.readAttribute('rel');
		if(rel && a.href){
			if(rel.substr(0,8) == 'framebox'){
				Event.observe(a, 'click', UI.box.frameClick);
			} else if(rel == 'closebox'){
				Event.observe(a, 'click', UI.box.closeClick);
			}
		}
	},
	
	// Click on close button
	closeClick: function(event){
		Event.stop(event);
		UI.box.remove();
	},

	// Click on frame link
	frameClick: function(event){
		Event.stop(event);
		UI.box.frameStart(Event.findElement(event, 'a'));
	},

	// Start framebox
	frameStart: function(a){
		var s = $(a).readAttribute('rel').split(' ');
		var w = (s.length > 1) ? s[1] : 0;
		var h = (s.length > 2) ? s[2] : 0;
		UI.box.frameShow(a.href, a.title, w, h);
	},

	// Build framebox
	frameShow: function(str, title, w, h){
		var overlay = UI.box.createOverlay();
		var div = $('box_iframe');
		if(!div){
			var txt = words[common.lang].toClose;
			var div = UI.create('div').setProperties({'id':'box_iframe', 'class':'box_window'}).injectInside(document.body);
			var a = UI.create('a').setHTML(txt).setProperties({'href':'#', 'title': txt, 'id':'box_close'}).injectInside(div);
			var iframe = UI.create('iframe').setProperties({'id':'box_iframe1', 'frameborder':'0', 'scrolling':'no', 'src':str}).injectInside(div);
			a.onclick = function(){
				return UI.box.remove();
			}

			var h1 = h - UI.box.titleHeight;
			if(w > 0){
				div.style.width = w + 'px';
				iframe.style.width = w + 'px';
			}
			if(h > 0){
				div.style.height = h + 'px';
				iframe.style.height = h1 + 'px';
			}
		}
		div.style.display = 'block';
		UI.box.overlaySize();
		UI.box.position(div);
		window.scroll(0, 0);
		window.onresize = function(){
			UI.box.overlaySize();
			UI.box.position(div);
		};
		window.onscroll = function(){
			UI.box.position(div);
		};
	},

	// Create iframe to hide <select>s on IE
	// Create shadow (except for KHTML browsers)
	createOverlay: function(){
		var overlay = $('box_overlay');
		if(!overlay){
			if(!UI.khtml){
				var iframe = UI.create('iframe').setProperty('id','box_hideSelect').injectInside(document.body);
			}
			var overlay = UI.create('div').setProperty('id','box_overlay').injectInside(document.body);
			overlay.onclick = function(){
				UI.box.remove();
			}
		}
		overlay.setStyle({'opacity': 0.1}); // IE bug
		new Effect.Opacity('box_overlay', {
			duration: UI.box.duration,
			from: 0,
			to: UI.box.opacity
		});
		return overlay;
	},

	// Remove framebox **from inside the iframe**
	remove: function(){
		var div = 'box_iframe';
		var overlay = $('box_overlay');
		overlay.onclick = null;
		window.onresize = null;
		window.onscroll = null;
		new Effect.Opacity('box_overlay', {
			duration: UI.box.duration,
			from: UI.box.opacity,
			to: 0
		});
		setTimeout(UI.box.removeCallback, UI.box.duration + 250);
		$(div).remove();
		return false;
	},

	// Remove overlays
	removeCallback: function(){
		var overlay = $('box_overlay');
		if(overlay){
			overlay.remove();
		}
		if(!UI.khtml){
			$('box_hideSelect').remove();
		}
	},

	// Position framebox
	position: function(div){
		var b = $(div);
		if(b){
			var pageSize = UI.box.getPageSize();
			var pageWidth = pageSize[0];
			var winWidth = pageSize[2];
			var boxWidth = b.getWidth();
			var l = (boxWidth > winWidth) ? "0" : winWidth/2 - boxWidth/2;
			b.setStyle({
				'left': l + 'px'
			});
		}
	},

	// Calculate overlay size
	overlaySize: function(){
		var pageSize = UI.box.getPageSize();
		var w = $(document.body).getWidth();
		$('box_overlay').setStyle({
			'height': pageSize[1] + 'px',
			'width': w + 'px'
		});
		if(!UI.khtml){
			$('box_hideSelect').setStyle({
				'height': pageSize[1] + 'px',
				'width': w + 'px'
			});
		}
	},

	// Method to be called from the framebox page
	// Automatically adapt framebox's size
	autoSize: function(){
		var p = window.parent;
		var f0 = p.$('box_iframe');
		var f1 = p.$('box_iframe1');
		if(f0 && f1){
			var pageSize = UI.box.getPageSize();
			var w = pageSize[0];
			var h = pageSize[1];
			var ww = $(p.document.body).getWidth();
			var l = (w > ww) ? "0" : ww/2 - w/2;
			f0.setStyle({
				'height': h + UI.box.titleHeight + 'px',
				'left': l + 'px',
				'width': w + 'px'
			});
			f1.setStyle({
				'height': h + 'px',
				'width': w + 'px'
			});
		}
	},

	// Get page size
	getPageSize: function(){
		var xScroll, yScroll;
		if (window.innerHeight && window.scrollMaxY) {	
			xScroll = window.innerWidth + window.scrollMaxX;
			yScroll = window.innerHeight + window.scrollMaxY;
		} else if (document.body.scrollHeight > document.body.offsetHeight){ // all but Explorer Mac
			xScroll = document.body.scrollWidth;
			yScroll = document.body.scrollHeight;
		} else { // Explorer Mac...would also work in Explorer 6 Strict, Mozilla and Safari
			xScroll = document.body.offsetWidth;
			yScroll = document.body.offsetHeight;
		}

		var windowWidth, windowHeight;
		if (self.innerHeight) {	// all except Explorer
			if(document.documentElement.clientWidth){
				windowWidth = document.documentElement.clientWidth; 
			} else {
				windowWidth = self.innerWidth;
			}
			windowHeight = self.innerHeight;
		} else if (document.documentElement && document.documentElement.clientHeight) { // Explorer 6 Strict Mode
			windowWidth = document.documentElement.clientWidth;
			windowHeight = document.documentElement.clientHeight;
		} else if (document.body) { // other Explorers
			windowWidth = document.body.clientWidth;
			windowHeight = document.body.clientHeight;
		}

		// for small pages with total height less then height of the viewport
		if(yScroll < windowHeight){
			pageHeight = windowHeight;
		} else {
			pageHeight = yScroll;
		}

		// for small pages with total width less then width of the viewport
		if(xScroll < windowWidth){
			pageWidth = windowWidth;
		} else {
			pageWidth = xScroll;
		}

		var pageSize = new Array(pageWidth,pageHeight,windowWidth,windowHeight) 
		return pageSize;
	}
};

///////////////////////////////////////////////////////////////////////////////
// Prototype.js extension
// Code from Mootools

UI.properties = {
	'class': 'className', 'for': 'htmlFor', 'colspan': 'colSpan', 'rowspan': 'rowSpan',
	'accesskey': 'accessKey', 'tabindex': 'tabIndex', 'maxlength': 'maxLength',
	'readonly': 'readOnly', 'frameborder': 'frameBorder', 'value': 'value',
	'disabled': 'disabled', 'checked': 'checked', 'multiple': 'multiple', 'selected': 'selected'
};

Element.addMethods({

	setMany: function(el, method, pairs){
		for (var key in pairs) el[method](key, pairs[key]);
		return el;
	},

	setProperty: function(el, property, value){
		el = $(el);
		var index = UI.properties[property];
		if (index) el[index] = value;
		else el.setAttribute(property, value);
		return el;
	},

	setProperties: function(el, obj){
		return el.setMany('setProperty', obj);
	},

	setHTML: function(el, str){
		el.innerHTML = str;
		return el;
	},

	inject: function(el, container, where){
		container = $(container);
		switch(where){
			case 'before':
				container.parentNode.insertBefore(el, container);
				break;
			case 'after':
				var next = container.next();
				if (!next) container.parentNode.appendChild(el);
				else container.parentNode.insertBefore(el, next);
				break;
			case 'top':
				var first = container.firstChild;
				if (first){
					container.insertBefore(el, first);
					break;
				}
			default:
				container.appendChild(el);
		}
		return el;
	},

	injectBefore: function(el, container){
		return el.inject(container, 'before');
	},

	injectAfter: function(el, container){
		return el.inject(container, 'after');
	},

	injectInside: function(el, container){
		return el.inject(container, 'bottom');
	},

	injectTop: function(el, container){
		return el.inject(container, 'top');
	}

});

