/**
 * @author Softbuilder OÜ
 */

sys3 = {}

sys3.dom = 
    {
    bindWithObject : function (elm, evt, obj, func)
    {
        var newFunc = function (elm2, evt, target)
        {
            //console.profile(evt);
			var ret = func.call(obj, elm2, evt, target);
			//console.profileEnd(evt);
			return ret;
        };

        this.addEventHandler(elm, evt, newFunc);
    },
    addEventHandler : function (element, eventName, handler)
    {
        var handler2 = function (evt)
        {
            evt = (evt) ? evt : ((event) ? event : null);

            if (evt)
            {
                var target = (evt.target) ? evt.target : ((evt.srcElement) ? evt.srcElement : null);

                if (target)
                    target = (1 == target.nodeType || 9 == target.nodeType) ? target : target.parentNode;

                return handler(element, evt, target);
            }

            return true;
        };

        if (element.attachEvent) {
			element.attachEvent('on' + eventName, handler2);
		}
		else 
			element.addEventListener(eventName, handler2, false);
    },
    cancelBubbling : function (evt)
    {
        evt.returnValue 	= false;
        evt.cancelBubble 	= true;

        if('preventDefault' in evt)
            evt.preventDefault();
    }
};

/*
 * register all animations, that are running, here.
 * This will check them all, every 40 ms 
 */
sys3.animatorStack = {
	stack: {},
	stackSize: 0,
	intervalID: null
}

sys3.animatorStack.add = function(animatorObj){
	this.stack[this.stackSize++] = animatorObj;
	if( this.intervalID == null){
		var context = this;
		var updateFunc = function(){
			context.update.call(context);
		}
		this.intervalID = setInterval(updateFunc,10);
	}
}

sys3.animatorStack.remove = function(animatorObj){
	for(var x in this.stack){
		if (this.stack[x] == animatorObj) {
			delete this.stack[x];
			this.stackSize--;
			if(this.stackSize <= 0){
				clearInterval(this.intervalID);
				this.intervalID = null;
			}
			return true;
		}
	}
	return false;
}

sys3.animatorStack.update = function(){
	var time = (new Date()).getTime();
	//console.log('stack.update',time);
	for(var x in this.stack){
		this.stack[x].update(time);
	}
}
/*
 * array of change objects [{styles:[styleToChange:value,styleToChange2:value],duration:value},{}]
 */
sys3.animator = function(obj, arrayOfChanges, returnFunc){
	this.obj = obj;
	this.returnFunc = returnFunc;
	//list original and end values for each style
	this.originalStyles = {};
	this.endStyles = {};
	this.durations = {};
	for(var x in arrayOfChanges){
		for(var y in arrayOfChanges[x].styles){
			this.endStyles[y] = sys3.styleParser(y, arrayOfChanges[x].styles[y]);
			this.durations[y] = arrayOfChanges[x].duration;
		}
	}
	//console.log(obj.style.height,this.originalStyles,this.endStyles);
}

sys3.animator.prototype.run = function(returnFunc){
	if(returnFunc)this.returnFunc = returnFunc;
	this.startTime = (new Date()).getTime();
	for(var y in this.endStyles){
		this.originalStyles[y] = sys3.styleParser(y, sys3.getStyle(this.obj,y));
	}
	sys3.animatorStack.add(this);
}

sys3.animator.prototype.update = function(time){
	//console.log('animator.update',time);
	var done = time - this.startTime;
	var styleTime, coef, styleValue;
	var finished = true;
	for(var x in this.endStyles){
		styleTime = this.durations[x];
		coef = done/styleTime;
		if(coef > 1)this.obj.style[x] = sys3.styleParserReverse(x, this.endStyles[x]);
		else{
			//only transition transitionable stuff
			//margins,paddings,font-size,font-weight,border-width and so on
			if(x == 'height' || x == 'width' || x == 'opacity'){
				styleValue = coef * ( this.endStyles[x] - this.originalStyles[x] ) + this.originalStyles[x];
				//console.log(x,coef,this.endStyles[x],this.originalStyles[x],this.originalStyles[x],styleValue);
				this.obj.style[x] = sys3.styleParserReverse(x, styleValue);
				//IE hack
				if (x == 'opacity') {
					this.obj.style.filter = 'alpha(opacity=' + styleValue * 100 + ')';
					//console.log(this.obj.style.filter, styleValue);
				}
			}
			finished = false;
		}
	}
	if(finished){
		sys3.animatorStack.remove(this);
		if(this.returnFunc)this.returnFunc();
	}
}


sys3.styleParser = function(property,value){
	/*
	 * very limited atm
	 */
	if(property == 'height' || property == 'width'){
		var i = value.indexOf('px');
		return parseInt(value.substring(0,i));
	}
	
	if(property == 'opacity'){
		var val = parseFloat(value);
		if(isNaN(val))val = 1;
		//console.log('val '+val);
		return val;
	}
	
	return value;
}

sys3.styleParserReverse = function(property, value){
	
	if(property == 'height' || property == 'value'){
		return value+'px';
	}
	
	if(property == 'opacity'){
		//console.log(value);
	}
	
	return value;
}


sys3.getStyle = function (x, styleProp){
	//change styleProp to match css notation instead of javascript notation for some browsers
	if(sys3.styleNamesJStoCSS[styleProp])styleProp = sys3.styleNamesJStoCSS[styleProp];
	if (x.currentStyle)
		var y = x.currentStyle[styleProp];
	else if (window.getComputedStyle)
		var y = document.defaultView.getComputedStyle(x,null).getPropertyValue(styleProp);
	return y;
}

sys3.styleNamesJStoCSS = {
	backgroundColor:'background-color'
}

	var testFunc2 = function(){
		var elm = document.getElementById('myAnimation');
		
		if (!elm) {
			//console.log && console.log('bailing', elm);
			return true;
		}
		
		
		/*
		var elements = elm.children;

		var parsedElements = [];
		for(var i = 0; i<elements.length;i++){
			if(elements[i].tagName == 'DIV')parsedElements.push(elements[i]);
		}
		//console.log(elements, parsedElements);
		var peo = []; //parsedElementsObjects
		for(var i = 0; i<parsedElements.length;i++){
			peo[i] = {};
			peo[i].header = parsedElements[i].getElementsByTagName('h1')[0];
			peo[i].image = parsedElements[i].getElementsByTagName('img')[0];
		}
		//console.log(peo[0]);
		
		var headerContainer = document.createElement('ul');
		var imageContainer = document.createElement('div');
		headerContainer.className = 'moving-image-header-container';
		imageContainer.className = 'moving-image-image-container';
		for(var i = 0 ; i < peo.length ; i++){
			var headerItem = document.createElement('li');
			headerItem.className = 'moving-image-header-item';
			headerItem.appendChild(peo[i].header);
			headerContainer.appendChild(headerItem);
			peo[i].image.className = 'moving-image-image-item';
			imageContainer.appendChild(peo[i].image);
		}
		elm.innerHTML = '';
		elm.appendChild(headerContainer);
		elm.appendChild(imageContainer);
		*/
		
		/*
		 * for static
		 */
		var headerContainer = elm.getElementsByTagName('ul')[0];
		var imageContainer = elm.getElementsByTagName('div')[0];
		
		var headerChildren = headerContainer.getElementsByTagName('li');
		var imageChildren = imageContainer.getElementsByTagName('img');
		
		var peo = [];
		
		for(var i = 0; i<headerChildren.length;i++){
			peo[i] = {};
			peo[i].header = headerChildren[i].getElementsByTagName('h1')[0];
			peo[i].image = imageChildren[i];
		}
		
		elm.style.display = 'block';
		
		var containers = {}
		containers.parent = elm;
		containers.headers = headerContainer;
		containers.images = imageContainer;
		//console.log('animate',arguments.callee.caller.name);
		new animate(peo, containers);
	}
	
	animate = function(elms, containers){
		if(elms.length == 0)return false;
		this.elms = elms;
		this.current = elms.length-1;
		this.ahc = 'moving-image-header-item-inner-active'; //active header class
		this.nhc = 'moving-image-header-item-inner'; //normal header class
		for(var i = 0; i< elms.length;i++){
			elms[i].header.className = this.nhc;
			elms[i].animator = new sys3.animator(
				elms[i].image,
				{
					1:{
						styles:{
							opacity:'.00'
						},
						duration:2000
					}
				}
			);
			sys3.dom.bindWithObject(elms[i].header, 'click', this, this.moveToItem);
		}
		
		sys3.dom.bindWithObject(containers.parent, 'mouseover', this, this.pause);
		sys3.dom.bindWithObject(containers.parent, 'mouseout', this, this.resume);
		
		this.paused = false;
		this.timeoutID = null;
		this.next();
	}
	
	animate.prototype.done = function(){
		/*
		var previous = this.current-1;
		if(previous < 0) previous = elms.length-1;
		elms[previous].image.style.zIndex = 0;*/
		//console.log('done');
		var context = this;
		//console.log('done', this);
		var func = function(){
			context.next.call(context);
		}
		if(this.timeoutID == null)this.timeoutID = setTimeout(func,3000);
	}
	
	animate.prototype.next = function(nextItem, ignorePause){
		//console.log('next', this.current);
		this.timeoutID = null;
		if (this.paused && !ignorePause) {
			return;
		}
		//console.log('next',this.current,nextItem,ignorePause);
		var elms = this.elms;
		elms[this.current].header.className = this.nhc;
		elms[this.current].image.style.zIndex = 1;
		var context = this;
		var retFunc = function(){
			context.done.call(context);
		}
		elms[this.current].animator.run(retFunc);
		if(! isNaN(nextItem))this.current = nextItem;
		else this.current++;
		if(this.current >= elms.length)this.current = 0;
		elms[this.current].image.style.zIndex = 0;
		elms[this.current].image.style.opacity = 1;
		elms[this.current].image.style.filter = 'alpha(opacity=100)';
		elms[this.current].header.className = this.ahc;
	}
	
	animate.prototype.pause = function(){
		this.paused = true;
	}
	
	animate.prototype.resume = function(){
		this.paused = false;
		var context = this;
		var func = function(){
			context.next.call(context);
		}
		if(this.timeoutID == null)this.timeoutID = setTimeout(func,3000);
	}
	
	animate.prototype.moveToItem = function(elm,evt,target){
		clearTimeout(this.timeoutID);
		for(var i = 0;i<this.elms.length;i++){
			if(this.elms[i].header == target){
				this.next(i, true);
				break;
			}
		}
	}
	
	//window.onload = testFunc2;
