/**	
	@author			nathaniel skulic <nate@skulic.name>
	@copyright 		Copyright 2007, Nathaniel Skulic. All Rights Reserved.
	@fileOverview	
*/

// requires oil.utility
GUI = {};
/* All functions related to element positioning and scrolling */

oil.position = GUI.Position = {
	entire_offset: function(element) {
		var valueT = 0, valueL = 0;
		do {
			valueT += element.offsetTop  || 0;
			valueL += element.offsetLeft || 0;
			element = element.offsetParent;
		} while (element);
		return {left:valueL, top:valueT};
	},
	scrollTo: function(element) {
		var pos = GUI.Position.entire_offset(element);
		return window.scrollTo(pos.left, pos.top);
	},
	scroll_to:function(element){

        // This is the element we will examine to see if it has any overflow on it or
        // any of its parents (we are creating an alias we can play around with)
        var elementOverflow = element;
        var valueT = 0, valueL = 0;

        // {{{ Go up the tree looking at each parent to see if it has a height that
        //     is different than the scroll height.  If it is we have a block element
        //     that has overflow set to 'auto' or 'scroll' and we are going to have
        //     to handle it differently.
		// }}}
        do
        {
            if (!elementOverflow.parentNode) { break; }

            valueT += elementOverflow.offsetTop  || 0;
            valueL += elementOverflow.offsetLeft || 0;

            if (elementOverflow.parentNode.offsetHeight < elementOverflow.parentNode.scrollHeight)
            {
				_log('Setting scoll on '+ elementOverflow.parentNode+' to '+valueL+','+valueT+' '+elementOverflow.parentNode.scrollHeight+' '+elementOverflow.parentNode.offsetHeight);
                //elementOverflow.parentNode.scrollTop  = valueT;
                //elementOverflow.parentNode.scrollLeft = valueL;
                // We are going to call this iteratively because there is a chance that
                // there are nested overflowed elements and we'll have to peform the scrolling
                // for each one
                GUI.Position.set_scroll(elementOverflow.parentNode, valueL, valueT);
				//GUI.Window.scroll_to_position(valueL, valueT);
                // Short-circuit, we don't want to do the rest of this stuff below now that
                // we've found am overflowed element
                break;
            }

            elementOverflow = elementOverflow.parentNode;
        } while (true);
        
         var pos = GUI.Position.entire_offset(element);
        GUI.Window.scroll_to_position(pos.left, pos.top);
        return element; 
    },
	fps:100,
	move:function(element, xdelta, ydelta, transition_time, transition_type){
		transition_type = transition_type || GUI.Position.linear;
		
		move_info = {
		element:element
		,x_start:element.offsetLeft
		,y_start:element.offsetTop
		};
		
		move_info.steps = oil.position.fps * (transition_time / 1000);
		move_info.delay = transition_time / move_info.steps;
		move_info.x_inc = xdelta / move_info.steps;
		move_info.y_inc = ydelta / move_info.steps;
		
		//if(xdelta<0) // move left
		//else if(xdelta>0) // move right   
		//else {}	// dont move
		//
		//if(ydelta<0) // move up
		//else if(xdelta>0) // move down
		//else {} // dont move
	
	
		var posX = move_info.x_start+transition_type(move_info.x_inc);
		var posY = move_info.y_start+transition_type(move_info.y_inc);
		
		element.style.left = posX + "px";
		element.style.top = posY + "px";
		
		log(move_info)
		
		setTimeout(oil.event.bind(this, 'move', [element, xdelta, ydelta, transition_time, transition_type] ), move_info.delay);
		
		
	},
	do_move:function(move_info){
	
	}
};

/* 

Effect.Move = Class.create(Effect.Base, {
  initialize: function(element) {
    this.element = $(element);
    if (!this.element) throw(Effect._elementDoesNotExistError);
    var options = Object.extend({
      x:    0,
      y:    0,
      mode: 'relative'
    }, arguments[1] || { });
    this.start(options);
  },
  setup: function() {
    this.element.makePositioned();
    this.originalLeft = parseFloat(this.element.getStyle('left') || '0');
    this.originalTop  = parseFloat(this.element.getStyle('top')  || '0');
    if (this.options.mode == 'absolute') {
      this.options.x = this.options.x - this.originalLeft;
      this.options.y = this.options.y - this.originalTop;
    }
  },
  update: function(position) {
    this.element.setStyle({
      left: (this.options.x  * position + this.originalLeft).round() + 'px',
      top:  (this.options.y  * position + this.originalTop).round()  + 'px'
    });
  }
});

// for backwards compatibility
Effect.MoveBy = function(element, toTop, toLeft) {
  return new Effect.Move(element, 
    Object.extend({ x: toLeft, y: toTop }, arguments[3] || { }));
};
 */


/* var fps = 100;
	function move(eleId, varX, varY, transTime) {
		if(eleId) {
			i = 0;
			oDiv = document.getElementById(eleId);
			startX = oDiv.style.left.replace(/px/, "") * 1;
			startY = oDiv.style.top.replace(/px/, "") * 1;
			steps = fps * (transTime / 1000);
			delay = transTime / steps;
			incX = varX / steps;
			incY = varY / steps;
		}
 		if (i <= steps) {
			var posX = Math.ceil(startX + (i * incX));
			var posY = Math.ceil(startY + (i * incY));
			oDiv.style.left = posX + "px";
			oDiv.style.top = posY + "px";
			i++;
			setTimeout("move()", delay);
		} else {
			// alert('done');
			return;
		}
	}
	
	 */
oil.effects = {
	fps:100
};
	 
GUI.Position.set_scroll = function(element, x, y){
	  element.scrollTop  = y;
	  element.scrollLeft = x;
  };
  
/* GUI.Utility.find_position = function (obj) {
    var curleft = curtop = 0;
    if (obj.offsetParent) {
        curleft = obj.offsetLeft;
        curtop = obj.offsetTop;
        obj = obj.offsetParent;
        while (obj = obj.offsetParent) {
            curleft += obj.offsetLeft;
            curtop += obj.offsetTop;
        }
    }
    return {x:curleft,y:curtop};
};

GUI.Utility.find_position_from_parent = function (obj) {
    var curleft = curtop = 0;
    if (obj.offsetParent) {
        curleft = obj.offsetLeft;
        curtop = obj.offsetTop;
        obj = obj.offsetParent;
        //while (obj = obj.offsetParent) {
            curleft += obj.offsetLeft;
            curtop += obj.offsetTop;

        //}
    }
    this.x = curleft;
    this.y = curtop;
    return this;
}; */


//transitions
oil.position.sinusodial = function(pos){
	return ((-Math.cos(pos*Math.PI)/2) + 0.5);
	//this transition is from script.aculo.us
}
GUI.Position.linear = function(pos){
	return pos;
}
GUI.Position.cubic = function(pos){
	return Math.pow(pos, 3);
}
GUI.Position.circ = function(pos){
	return Math.sqrt(pos);
}



/* 
var fx = new Object();
//base
fx.Base = function(){};
fx.Base.prototype = {
 setOptions: function(options) {
 this.options = {
 duration: 500,
 onComplete: '',
 transition: fx.sinoidal
 }
 Object.extend(this.options, options || {});
 },

 step: function() {
 var time = (new Date).getTime();
 if (time >= this.options.duration+this.startTime) {
 this.now = this.to;
 clearInterval (this.timer);
 this.timer = null;
 if (this.options.onComplete) setTimeout(this.options.onComplete.bind(this), 10);
 }
 else {
 var Tpos = (time - this.startTime) / (this.options.duration);
 this.now = this.options.transition(Tpos) * (this.to-this.from) + this.from;
 }
 this.increase();
 },

 custom: function(from, to) {
 if (this.timer != null) return;
 this.from = from;
 this.to = to;
 this.startTime = (new Date).getTime();
 this.timer = setInterval (this.step.bind(this), 13);
 },

 hide: function() {
 this.now = 0;
 this.increase();
 },

 clearTimer: function() {
 clearInterval(this.timer);
 this.timer = null;
 }
}

//stretchers
fx.Layout = Class.create();
fx.Layout.prototype = Object.extend(new fx.Base(), {
 initialize: function(el, options) {
 this.el = $(el);
 this.el.style.overflow = "hidden";
 this.iniWidth = this.el.offsetWidth;
 this.iniHeight = this.el.offsetHeight;
 this.setOptions(options);
 }
});

fx.Height = Class.create();
Object.extend(Object.extend(fx.Height.prototype, fx.Layout.prototype), {
 increase: function() {
 this.el.style.height = this.now + "px";
 },

 toggle: function() {
 if (this.el.offsetHeight > 0) this.custom(this.el.offsetHeight, 0);
 else this.custom(0, this.el.scrollHeight);
 }
});

fx.Width = Class.create();
Object.extend(Object.extend(fx.Width.prototype, fx.Layout.prototype), {
 increase: function() {
 this.el.style.width = this.now + "px";
 },

 toggle: function(){
 if (this.el.offsetWidth > 0) this.custom(this.el.offsetWidth, 0);
 else this.custom(0, this.iniWidth);
 }
});

//fader
fx.Opacity = Class.create();
fx.Opacity.prototype = Object.extend(new fx.Base(), {
 initialize: function(el, options) {
 this.el = $(el);
 this.now = 1;
 this.increase();
 this.setOptions(options);
 },

 increase: function() {
 if (this.now == 1 && (/Firefox/.test(navigator.userAgent))) this.now = 0.9999;
 this.setOpacity(this.now);
 },

 setOpacity: function(opacity) {
 if (opacity == 0 && this.el.style.visibility != "hidden") this.el.style.visibility = "hidden";
 else if (this.el.style.visibility != "visible") this.el.style.visibility = "visible";
 if (window.ActiveXObject) this.el.style.filter = "alpha(opacity=" + opacity*100 + ")";
 this.el.style.opacity = opacity;
 },

 toggle: function() {
 if (this.now > 0) this.custom(1, 0);
 else this.custom(0, 1);
 }
}); */
