// JavaScript Document

var Tabs = new Class({

  Implements: [Events, Options],
	
	options: {
		tabs: '.tab-anchors li',
		panels: '.tab-panel',
		disableClass: 'disabled',
		start: 0,
		observeDuration: 200,
		forceLinks: false
		//onShow: $empty(tab, panel, anchor),
		//onClose: $empty(tab, panel, anchor),
		//onReady: $empty()
	},
	
	initialize: function(container, options){
		
		this.setOptions(options);
		this.container = document.id(container);
		this.tabs = new Hash(); // contains pairs of tabs and panels with anchor as id
		this.anchors = new Array(); // contains all available tab ids
		this.handlers = this.container.getElements(this.options.tabs);
		
		this.current = null;
		this.defaultTab = null;

    this.handlers.each(function(handler){
		   this.addTab(handler);
			 var link = handler.getElement('a');
			 if (handler.hasClass('disabled') && link){
				 link.addEvent('click', function(event){
				   event.preventDefault()
				 });
			 }
			 if (handler.hasClass('default')){
				 this.defaultTab = link.get('href').replace('#','');
			 }
		}, this);
		
		// init default tab
		if (!this.defaultTab) this.defaultTab = this.anchors[this.options.start];
		var hash = new URI().get('fragment');
		var onLoadScroll = false;
    if (this.tabs.has(hash)){
			 this.defaultTab = hash;
		} else {
			var targetElement = document.id(hash);
			if (targetElement){
				var panelID = this.getTabFromElement(targetElement);
				if (panelID) this.defaultTab = panelID;
				onLoadScroll = true;
			}
		}
		if (this.defaultTab){
			this.show(this.defaultTab);
			if (onLoadScroll){
				var position = document.id(hash).getPosition(document.body);
				document.id(document.body).scrollTo(0, position.y);
			}
		}
		
		// force links
		if (this.options.forceLinks){
			var links = document.id(document.body).getElements('a[href^=#]');
			links.each(function(link){
				var anchor = link.get('href').replace('#','');
				if (anchor){
					link.addEvent('click', function(event){
					  event.preventDefault();
						this.show(anchor)
					}.bind(this));
				}
			}, this);
		} else {
			// run observer
			this.repeater = this.observe.periodical(this.options.observeDuration, this);
		}
		this.container.addClass('ready');
		this.fireEvent('ready', this);
		
		return this;
		
	},
	
	addTab: function(handler){
		var anchor = handler.getElement('a').get('href');
    if (anchor.test(/^#(.)+$/)){
			var panel =  this.container.getElement(anchor);
			if (panel){
				anchor = anchor.replace('#', '');
				this.tabs.set(anchor, {
				  tab: handler,
					panel: panel.removeProperty('id').hide(),  // remove id to prevent browser from jumping in page
					anchor: anchor
				});
				this.anchors.include(anchor);
			}
		}
	},
	
	getTabFromElement: function(element){
		var tabKey = null;
		if (!element) return tabKey;
		
		var panel = element.getParent('div.tab-panel');
		
		if (!panel) return tabKey;
		
		this.tabs.each(function(tab, key){
			if (tab.panel.uid == panel.uid){
				tabKey = key;
			}
		});
		
		return tabKey;
	},
	
	show: function(id){
		if (id == '') id = this.defaultTab;
		if (this.tabs.has(id)){
			var tabPanel = this.tabs.get(id);
			if (this.current){
				this.current.tab.removeClass('active');
				this.current.panel.hide();
				this.fireEvent('close', [this.current.tab, this.current.panel, this.current.anchor]);
			}
			var tabPanel = this.tabs.get(id);
			tabPanel.tab.addClass('active');
			tabPanel.tab.getElement('a').blur();
			tabPanel.panel.show();
			this.current = tabPanel;
			
			if (this.options.forceLinks) window.location.hash = '#'+id;
      this.fireEvent('show', [tabPanel.tab, tabPanel.panel, id]);
			
			this.fireEvent('change', this.tabs);
		}
	},
	
	observe: function(){
		var hash = window.location.hash.replace('#', '').toString();
		var current = this.current.anchor.toString();
		if (hash != current && hash != ''){
     this.show(hash);
		}
	},
	
	toElement: function(){
		return this.container;
	}
		
});

// observe click events and calls registered methods
var Observer = {
	
	init: function(){
		this.body = document.id(document.body);
		
		this.body.addEvent('click', this.check.bind(this));
		
		this.stack = new Array();
		
	},
	
	register: function(func, bind){
		this.stack.include(func.bind(bind));
		return func;
	},
	
	unregister: function(func){
		this.stack.erase(func);
		return func;
	},
	
	check: function(){
		this.stack.each(function(func){
		  if (func != undefined) func.run();
			this.unregister(func);
		}, this);
	}
 };
 
var Status = new Class({

  status: null,
	
	is: function(type){
		return (this.status != null ? this.status.get(type) : null);
	},
	
	isNot: function(type){
		return !this.is(type);
	},
	
	setStatus: function(type, value){
		if (this.status == null) this.status = new Hash();
		this.status.set(type, value)
	},
	
	getStatus: function(type){
	  return (this.status != null ? this.status.get(type) : null);
	},
	
	getStatusData: function(){
		return this.status;
	}

});
