/**
 * gets the path to the current script
 */
function getScriptPath() {
	var scripts = document.getElementsByTagName('script');
	var index = scripts.length - 1;
	var myScript = scripts[index];
	return new URI(myScript.src);
};

var JPATH_ROOT = getScriptPath().toString().replace(/\/media.*/,'');

/**
 * A bug fix in Mootools for IE. When getting an attribute of a form that has the same name 
 * as one of the form elements
 * @param {string} attribute
 */

Element.alias('getProperty','_getProperty');

Element.implement({
	getProperty: function(attribute){
		var value = this._getProperty(attribute);
		if (value === null && this.tagName == 'FORM' && Browser.Engine.trident) {
			var node = this.getAttributeNode(attribute);
			if (node) 
				value = node.nodeValue;
		}
		return value;
	}
});

/**
 * IE Node constants
 */

if (!window['Node']) {
    window.Node = new Object();
    Node.ELEMENT_NODE = 1;
    Node.ATTRIBUTE_NODE = 2;
    Node.TEXT_NODE = 3;
    Node.CDATA_SECTION_NODE = 4;
    Node.ENTITY_REFERENCE_NODE = 5;
    Node.ENTITY_NODE = 6;
    Node.PROCESSING_INSTRUCTION_NODE = 7;
    Node.COMMENT_NODE = 8;
    Node.DOCUMENT_NODE = 9;
    Node.DOCUMENT_TYPE_NODE = 10;
    Node.DOCUMENT_FRAGMENT_NODE = 11;
    Node.NOTATION_NODE = 12;
}
var Uikit = {};

/**
 * Centralized Uikit Event Center
 */
Uikit.EventCenter = new Events();

/**
 * Uikit Tab
 * @param {Object} container
 */
Uikit.Tab = new Class({
		initialize : function(container) {
			new Uikit.Events({
				'window domready' : function() {
					new TabSwapper({
						  selectedClass  : 'an-se-on',
						  deselectedClass: 'an-se-off',
						  tabs: $$(container + ' .an-se-tabset li'),
						  clickers: $$(container + ' .an-se-tabset li a'),
						  sections: $$(container + ' .an-se-tabpanel'),
						  smooth: true,
						  smoothSize: true		
					});
				}
			});
		}
});


/**
 * An Utility to addEvents to elements. It atttaches a number of events to the element using selectors
 * 
 * @example
 * new Uikit.Events({
 *  '#myelement click' : function(event, myelement) {
 *     event.stop();
 *  },
 *  '.myelements domready' : function(event, element) {
 *    
 *  } 
 * })
 * 
 * you can also bind all the event handler to an object by setting the bind parameter
 * 
 * @example 
 * 
 * var MyClass  = new Class({});
 * myobject = new MyClass();
 * new Uikit.Events({
 *   bind :  myobject,
 *   'window domready' : function(e, el) {
 *     this === myobject //true
 *   }
 *   
 * })
 * 
 */
Uikit.Events = new Class({
	Implements    :		[Events, Options],
	nativeEvents  : 	{'domready' :$empty,'load':$empty,'click':$empty,'dblclick':$empty,'mousedown':$empty,'mousemove':$empty,'mouseout':$empty,'mouseover':$empty,'mouseup':$empty,'keydown' : $empty, 'keyup' : $empty,'keypress' : $empty,'submit':$empty,'reset':$empty,'change':$empty,'select':$empty,'blur':$empty,'focus':$empty},						
	registeredTargets : {},
	elementsSelectors : [],
	id				  : null,
	options 	      : {
		namespace  : null ,
		substitute : null ,
		bind	   : null
	},
	addEvents	  : function() {
		$each(arguments,function(arg) {
			this.nativeEvents[arg] = $empty;
		}.bind(this));
	},
	initialize    : function(options) {
		//some randome id
		this.id = $random(0,$time());
		
		this.setOptions(options);
		
		this.options.bind = this.options.bind || this;
		
		if ( options['window domready'] ) {
			window.addEvent('domready', options['window domready'].bindWithEvent(this.options.bind));
			delete options['window domready'];
		}
		
		/*
		assignment_events = null;
		
		for(key in this.options.substitute || {}) {
			element = this.options.substitute[key];
			if ( !assignment_events )
				assignment_events   = {};
			assignment_events[element + ' domready'] = function(e, variable, element) {	
			}.bindWithEvent(this,[key, element]);
		}
		if ( assignment_events )
			new Uikit.Events(assignment_events);
		*/
		
		for(key in options) {
		
			value = options[key];
						
			if ( !key.match(/ /)) continue;			
	
			if ( this.options.bind ) 
				value = value.bind(this.options.bind);
			

			if ( this.options.substitute && key.match(/\{/) ) {								
				key =  key.substitute( this.options.substitute );
			}

			this[key] = value;
		}
		
		if (this.options.namespace)
			this.namespaceMethods(this.options.namespace);
		
		this.elementsSelectors = this.getCssSelectors();
		
		window.addEvent('domready', this.registerEvents.bind(this));
		
		if (!Uikit.Events.instances)
			Uikit.Events.instances = {}
			
		Uikit.Events.instances[this.id] = this;
		
	},
	namespaceMethods : function(namespace) {
		if (!namespace)
			return;
		for(method in this) {
			if (method.match(/ \w+$/) && method.indexOf(namespace) == -1) {
				newMethod = namespace + ' ' + method;
				this[newMethod] = this[method]
				delete this[method];
			}
		}
	},
	getCssSelectors : function() {
		selectors   = [];
		properties  = $H(this).getKeys()
		for (i = 0; i < properties.length; i++) {
			var property = new String(properties[i]);
			value = this[property];
			
			if ($type(value) != 'function') 
				continue;
			if (!property.test(/ \w+$/)) 
				continue;
				
			e = property.match(/\w+$/);
			
			if (!this.nativeEvents[e]) 
				continue;
			css = property.replace(" " + e, '');
			
			if ( css.indexOf(',') != -1 ) {
				this[css] = null;
				csss = css.split(',');
				for(j=0;j < csss.length;j++) {
					handler = csss[j] + " " + e;
					this[handler] = value;
					selectors.push(csss[j]);
				}
			} else {
				selectors.push(css);
			}

			
		}
		return selectors;
	},
	registerEvents : function(DOM) {
		domspace = $(DOM || document)
		if (this.logging)
			log((this.name ? this.name + '('+  this.id + ')' : this.id) + ' Controller:registerEvents',domspace);
		for(i=0;i<this.elementsSelectors.length;i++) {
			selector = this.elementsSelectors[i];
			targets  = domspace.getElements(selector);
			count	 = 0;
			for(j=0;j<targets.length;j++) {
			
				target = targets[j];
				if (!(uniqueId = target.get('element_id'))) {
					uniqueId = $random(0, $time());
					target.set('element_id', uniqueId);
				}
				
				if  (!this.registeredTargets[uniqueId]) {
					this.registeredTargets[uniqueId] = [selector];
				} else if  (!this.registeredTargets[uniqueId].contains(selector)) {					
					this.registeredTargets[uniqueId].push(selector)
				} else {

					continue;
				}
				count++;
				for(e in this.nativeEvents) {
					handler = selector + " " + e;
					if (this[handler]) {
					if (this.logging)
						log((this.name ? this.name + '('+  this.id + ')' : this.id) + ' Controller:registerHandler: ' + handler);						
						target.addEvent(e, this[handler].bindWithEvent(this, [target]));
					}
				}				
			}
			
			if (this.logging)
				log((this.name ? this.name + '('+  this.id + ')' : this.id) + ' Controller:'+selector+' - F('+targets.length+') R('+ count +')');
		}
	}
	
});

//Register all the instances of the UiKit.Events
Uikit.Events.register = function(element) {
	if ( !Uikit.Events.instances ) return;
	for (id in Uikit.Events.instances) {
		instance = Uikit.Events.instances[id];
		instance.registerEvents(element);
	}
};

/**
 * 
 */
Uikit.Events.XHR = {
	onSuccess: function(tree, elements, html){
		this.previous.apply(this, arguments);
		if (this.options.inject) {
		
			var options = this.options.inject;
			
			if ($type(options) == 'string' || $type(options) == 'element') {
				options = {
					element: document.id(options)
				}
			}
			
			var default_options = {
				where: 'top',
				duration: 'long',
				transition: Fx.Transitions.Bounce.easeOut
			};
			
			options = $merge(default_options, options);
			
			var element = options.element;
			
			for (i = 0; i < tree.length; i++) {
				node = tree[tree.length - 1 - i];
				if (node.nodeType == Node.ELEMENT_NODE) {
					node.inject(element, options.where);
					var fx = new Fx.Slide(node, {
						duration: options.duration,
						transition: options.transition
					}).hide().slideIn().chain(function(){
						node.replaces(fx.wrapper);
						node.setStyle('margin', null);
					});
				};
							};
					};
		
		Uikit.Events.register();
	}
}

//Make sure after a Request.HTML the events are re-registered
Request.HTML = Class.refactor(Request.HTML, Uikit.Events.XHR); 

/**
 * Uikit Modal
 * creates a standard uikit modal
 */
Uikit.Modal  = function(options) {
	
	this.options  =  {
		url     : null ,
		element : null ,
		html    : null ,
		allowMultiple : false,
		showNow : true,
		width	  : '600px',
		uiOptions    : {
			dismiss	 : 'Cancel'
		},
		modalOptions: {
		    modalStyle: {		      
		      'opacity':0
		    }
		}
	}
	options     = $merge(this.options, options || {});
	uiOptions   = $merge({width:options.width}, options.uiOptions);
	delete options.uiOptions;
	if (options.url) 
	{
		modal = this;
		options.handleResponse = function(response) 
		{
			var html = Uikit.ModalBuilder.build(this, response, uiOptions);
			this.setContent(html);
			this.position().pin();
			var scripts = '';
			this.Request.response.text.stripScripts(function(script){
				scripts += script;
			});
			eval(scripts);
			Uikit.Events.register(html);
			(options.onContentLoad || $lambda).apply(modal);
		}
		var win = new StickyWin.Fx.Ajax(options);
		win.setContent(Uikit.ModalBuilder.build(win, 'Loading...', uiOptions));
		win.show();
		win.update();
		return win;
	} else 
	{
		var win = new StickyWin.Fx(options);
		if ( options.element ) 
				options.html = options.element.get('html');
		
		win.setContent(Uikit.ModalBuilder.build(win, options.html,uiOptions));
		return win;
	}	
};


/**
 * Helper to build a modal from a HTML 
 * @param {Object} html
 * @param {Object} options
 */
Uikit.ModalBuilder = {
		
		/**
		 * Build a modal 
		 */
		build : function(modal, html, options) 
		{
			var options = $merge({
				'dismiss' : 'Cancel'
			},options || {});
			
			if ( $type(html) == 'string' ) 
				html = new Element('div', {'html':html});
			
			var caption  = html.getElement('h1');
			
			if (caption) 
			{
				caption.dispose();
				caption = caption.get('text');
			}
			var buttonSet 	= html.getElement('.an-se-buttons');
			var buttons     = [];
			if (buttonSet) 
			{
				buttons 	= buttonSet.getChildren().map(function(button) {
					var onclick = function(button)
					{
						var name = button.get('name');
						
						if ( name )
							this.fireEvent(name,[button]);
						
						this.fireEvent('buttonClick',[button]);
						
						(button.onclick || $empty).apply(modal);
						
					}.bind(modal, [button]);
					var b = {
							'text'    :  button.get('html') || button.get('value'),
							'onClick' :  onclick,
							'properties' : {
								'class'  : 'buttonSticky ' + button.get('class'),
								'id'	 :  button.get('id') ,
								'name'   :  button.get('name')
							}
					};
					return b;
				})
				buttonSet.dispose();
			}	
			if (options.dismiss )
				buttons.unshift({
					text:options.dismiss ,
					onClick : options.onDismiss || function() {
						
					}
				});	
			
			options = $merge(options,{buttons:buttons});
			
			if (options.pointy) 
			{
				options =  $merge(options,{closeButton:false});	
				var html = $(new StickyWin.UI.Pointy(caption, html,options));
				if (options.closeButton)
					html.getElement('.closeButton.closeSticky').addEvent('click',function(){
						html.dispose();
					})
				return html;
			} else 
				return document.id(new StickyWin.UI(caption, html, options));	
	}
};



/**
 * Uikit.Events.Remove
 */
Uikit.Events.RemoveRecords = new Class({
	
	initialize : function() {
		new Uikit.Events({
			bind : this ,
			'.an-se-removable domready' : this.addHandle
		});
	},
	addHandle : function(e, el) {
		var handle = el.getElement('.an-se-remove-handle');
		if (handle) {
			handle.store('record',el);
			handle.addEvent('click', this.removeRecord.bindWithEvent(this, [handle]));			
		}
	},
	removeRecord : function(e,handle) {
		e.stop();
		
		var removeReq = new Request({
			url : handle.href,
			onSuccess : this.onRecordRemove.bind(this,[handle,removeReq])
		});
		
		if (handle.hasClass('an-se-confirm-remove')) {
			this.confirmRemove(handle,removeReq);
		} else 
			removeReq.post();
	},
	onRecordRemove : function(handle,req) {	 
		if (handle.get('redirect')) {
			window.location = handle.get('redirect');
		}
		else {
			var record = handle.retrieve('record');
			record.destroy();
		}
	},
	
	confirmRemove : function(handle,removeReq) {
		var options = JSON.decode(handle.get('remove_options') || '{}');
		options.pointyOptions = $merge({
			width:200   ,
			point:'left',
			closeButton:false,
			redirectUrl: null
		},options);
		
		handle.set('redirect', options.redirect);
		
		var body = new Element('div', {
			'class': 'an-se-modal-pointy'
		});
		
		var title = new Element('div', {
			'html': options.title,
			'class': 'an-se-modal-pointy-title'
		});
		
		var text = new Element('div', {
			'html': options.text || '',
			'class': 'an-se-modal-pointy-body'
		});
		
		var buttonset = new Element('div', {
			'class': 'an-se-modal-pointy-button-set'
		});
		var cancelBtn  = new Element('button',{html:'Cancel','class' : 'button an-se-modal-pointy-button'}).inject(buttonset);
		var confirmBtn = new Element('button',{html:options.confirm || 'Ok','class' : 'button an-se-modal-pointy-button'}).inject(buttonset);
				
		body.adopt(text).adopt(buttonset);
		
		var sticky = new StickyWin.PointyTip(title,body,$merge(options,{relativeTo:handle,allowMultiple:false}));
		cancelBtn.addEvent('click',sticky.hide);
		confirmBtn.addEvent('click',function(){
			sticky.hide();
			removeReq.post();
		});
	}
});

new Uikit.Events.RemoveRecords();

