/**
 * @author Andre Haveman, Informaat
 */



/**************************************************************************************************
 * Style switcher component
 */
IUX.StyleSwitcher = {
	activeStyle : "initial",
	activeLink : null,
	
	init : function(){
		// read style from cookie
		var savedStyle = Cookie.get("IUXStyle") || "Linea";
		this.styleLinks = $A(document.getElementsByTagName("link"));
		if (savedStyle && savedStyle != this.activeStyle){
			this.setActiveStyleSheet(savedStyle);
		} else {
			this.showActive();
		}
		this.element = $("style-switcher");
		this.makeDraggable();
		
		// add click behaviour to style switcher links
		this.switchLinks = $$("#switching a");
		this.switchLinks.each(function(lnk){
			lnk.addEvent("click",this.selectStyle.bindAsEventListener(this,lnk));
			lnk.addEvent("mousedown",function(evt){
				var event = new Event(evt);
				event.stop();
			});
		}.bind(this));
		
		// initialize carousel
		this.Carousel.init(this.switchLinks.length);
	},
	
	selectStyle : function(evt,lnk){
		if (evt){
			var event = new Event(evt);
			event.stop();
		}
		var styleTitle = lnk.id;
		if (styleTitle && styleTitle != this.activeStyle) this.setActiveStyleSheet(styleTitle);
	},
	
	setActiveStyleSheet : function(title){
		this.styleLinks.each(function(lnk){
			var lnkTitle = lnk.getAttribute("title");
			if(lnk.getAttribute("rel").indexOf("style") != -1 && lnkTitle) {
				//if(lnkTitle == this.activeStyle) {
					lnk.disabled = true;
				//}
				if(lnkTitle == title) {
					lnk.disabled = false;
				}
				
			}
		}.bind(this));
		
		this.fireEvent("onStyleSwitch",[this.activeStyle,title]);
		this.activeStyle = title;
		this.showActive();
		Cookie.set("IUXStyle", title, {duration: 365, path: "/"});
	},
	
	showActive : function(){
		if (this.activeLink){
			this.activeLink.getParent().removeClass("active");
		}
		this.activeLink = $(this.activeStyle);
		if (this.activeLink) this.activeLink.getParent().addClass("active");
	},
	
	makeDraggable : function(){
		var savedPosition = Cookie.get("IUXSwitcherPosition");
		if (savedPosition){
			savedPosition = Json.evaluate(savedPosition);
			this.element.setStyle("top",savedPosition.y);
			this.element.setStyle("left",savedPosition.x);
		}
		var show = new Fx.Style(this.element,"opacity",{duration:500,wait:false});
		show.set(0);
		this.element.setStyle("display","block");
		this.keepInView();
		show.start(1);
		var timer = show.start.delay(3000,show,.2);
		
		this.elementSize = this.element.getSize().size;
		this.drag = new Drag.Move(this.element,{
			//limit:{x:[0,window.getWidth()-this.elementSize.x],y:[0,window.getHeight()-this.elementSize.y]},
			onComplete: function(){
				this.element.setStyle("position","fixed");
				var currPosition = Json.toString(this.element.getPosition());
				Cookie.set("IUXSwitcherPosition", currPosition, {duration: 365, path: "/"});
			}.bind(this)
		});
		this.element.setStyle("position","fixed");
		this.element.addEvents({
			"mouseenter":function(){
				if (timer) $clear(timer);
				timer = show.start.delay(200,show,1);
			},
			"mouseleave":function(){
				if (timer) $clear(timer);
				timer = show.start.delay(3000,show,.2);
			}
		});
		window.addEvent("resize",this.keepInView.bind(this));
	},
	
	keepInView : function(){
		var winW = window.getWidth();
		var winH = window.getHeight();
		if (this.element.getLeft() > winW-80){
			this.element.setStyle("left",winW-80+"px");
		}
		if (this.element.getTop() > winH-80){
			this.element.setStyle("top",winH-80+"px");
		}
		//this.drag.options.limit = {x:[0,window.getWidth()-this.elementSize.x],y:[0,window.getHeight()-this.elementSize.y]}
	}
}
$extend(IUX.StyleSwitcher,new Events);


IUX.StyleSwitcher.Carousel = {
	init : function(nrItems){
		// initialize carousel
		this.carousel = new Carousel("dhtml-carousel", {
				numVisible: 3,
				animParameters: {duration:500},
				scrollInc: 3,
				prevElementID: "prev-arrow",
				nextElementID: "next-arrow",
				size: nrItems,
				buttonStateHandler: this.handleButtonState.bind(this)
			}
		);
		$("prev-arrow").addEvent("mousedown",function(evt){
				var event = new Event(evt);
				event.stop();
		});
		$("next-arrow").addEvent("mousedown",function(evt){
				var event = new Event(evt);
				event.stop();
		});
	},
	
	handleButtonState : function(button, enabled) {
		$(button).src = "presentation/base/" + ((button == 'prev-arrow') ? "left" : "right") + (enabled ? "-enabled" : "-disabled") + ".gif";
	}
}

/**************************************************************************************************
 * Carousel Class
 * @param {Object} element
 */

/** Original script from:
 * Copyright (c) 2006 S??bastien Gruhier (http://xilinus.com, http://itseb.com)
 *  
 * Permission is hereby granted, free of charge, to any person obtaining
 * a copy of this software and associated documentation files (the
 * "Software"), to deal in the Software without restriction, including
 * without limitation the rights to use, copy, modify, merge, publish,
 * distribute, sublicense, and/or sell copies of the Software, and to
 * permit persons to whom the Software is furnished to do so, subject to
 * the following conditions:
 * 
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

 * VERSION 0.26
 * 
 * May 2007, Andre Haveman: Ported to the Mootools JavaScript library
 */

var Carousel = new Class({
  	// Constructor
	initialize: function(carouselElemID) {
		this.carouselElemID = carouselElemID;
		
		this.options = Object.extend({
			numVisible:           4,
			scrollInc:            3,
			animParameters:      {},
			buttonStateHandler:  null,
			animHandler:         null,
			ajaxHandler:         null,
			initDoneHandler:     null,
			queue:               "carousel",
			size:                0,
			prevElementID:       "prev-arrow",
			nextElementID:       "next-arrow",
			ajaxParameters:      null,
			url:                 null
		}, arguments[1] || {});
	
		this.initDone = false;
		this.animRunning = "none";
		this.requestIsRunning = false;
		
		// add afterFinish options to animParameters (store old function)
		this.animAfterFinish = this.options.animParameters.onComplete;
		$extend(this.options.animParameters, {onComplete:  this._animDone.bind(this)});
		  
		// Event bindings
		this.prevScroll = this._prevScroll.bindAsEventListener(this);
		this.nextScroll = this._nextScroll.bindAsEventListener(this);
		this.onComplete = this._onComplete.bindAsEventListener(this);
		this.onFailure  = this._onFailure.bindAsEventListener(this);
		
		this.prevButton = $(this.options.prevElementID);
		this.nextButton = $(this.options.nextElementID);
		this.prevButton.addEvent("click", this.prevScroll);
		this.nextButton.addEvent("click", this.nextScroll);
			
		// Get DOM UL element
		var carouselListClass = "carousel-list";
		this.carouselList = document.getElementsByClassName(carouselListClass, $(carouselElemID))[0];
		
		this.carouselClipRegion = document.getElementsByClassName("carousel-clip-region", $(carouselElemID))[0]
		this.carouselClipRegion.scrollLeft = 0;
		// Init data
		this._init();
	},
  
  // Destructor
	destroy: function() {
		this.prevButton.removeEvent("click", this.prevScroll);
		this.nextButton.removeEvent("click", this.nextScroll);
	},
	
	scrollTo: function(newStart) {
		var old_inc = this.options.scrollInc;
		this.ignoreNoMoreImages = true;
		if(newStart > this.currentIndex) {
			this.options.scrollInc = newStart - this.currentIndex;
			this._nextScroll(this);
		} else {
			this.options.scrollInc = this.currentIndex - newStart;
			this._prevScroll(this);
		}
		this.options.scrollInc = old_inc;
	},
	
	/* "Private" functions */
	_init: function() {
		this.currentIndex = 0;
		this.carouselList.setStyle("left","0px");
		// Ajax content
		if (this.options.url)
			this._request(this.currentIndex, this.options.numVisible);
		// Static content
		else {
			this._getLiElementSize();
			this._updateButtonStateHandler(this.options.prevElementID, false);
			this._updateButtonStateHandler(this.options.nextElementID, this.options.size > this.options.numVisible);
		}
	},
  
	_prevScroll: function(event) {
		if (this.animRunning != "none" || this.currentIndex == 0)
			return;

		var inc = this.options.scrollInc;

		if (this.currentIndex - inc < 0)
			inc = this.currentIndex;

		this._scroll(inc);  
  		return false;
	},

	_nextScroll: function(event) {    
		if (this.animRunning != "none")
  			return false;

		// Check if there are enough elements in cache
		if (this.currentIndex + this.options.numVisible + this.options.scrollInc <= this.options.size) 
			this._scroll(-this.options.scrollInc);
		else {
		// Compute how many are in the cache
			this.nbInCache = this.options.size - (this.currentIndex + this.options.numVisible);
			if (this.options.url && this.noMoreImages == false) 
				this._request(this.currentIndex + this.options.numVisible + this.nbInCache, this.options.scrollInc - this.nbInCache);
			else  {
				if (this.nbInCache > 0)
				this._scroll(-this.nbInCache);
			}
		}
		return false;
	},

	_request: function(start, nb) {
		if (this.options.url && ! this.requestIsRunning) {
			this.requestIsRunning = true;
		
		if (this.options.ajaxHandler)
			this.options.ajaxHandler(this, "before");
		
		var params = "start=" + start + "&nb=" + nb;
		if (this.options.ajaxParameters != null)
			params += "&" + this.options.ajaxParameters;
			var myAjax = new Ajax(this.options.url, {postBody: params, onComplete: this.onComplete});
			myAjax.request();
		}
	},
  
	_onComplete: function(originalRequest){
		this.requestIsRunning = false;
		this.carouselList.innerHTML += originalRequest.responseText;
		// Compute how many new elements we have
		var size = this.options.size;
		this.options.size = this.carouselList.getElementsByTagName("li").length;
		var inc = this.options.size - size;
	
		// First run, compute li size
		if (this.initDone == false) {
			this._getLiElementSize()
			this.currentIndex = 0;
			this.initDone = true;
			if (this.options.initDoneHandler)
				this.options.initDoneHandler(this);
		 
			// Update button states
			this._updateButtonStateHandler(this.options.prevElementID, false);
			this._updateButtonStateHandler(this.options.nextElementID, this.options.size == this.options.numVisible);
			this.noMoreImages = this.options.size < this.options.numVisible;
		}
		// Add images
		else {
			if (!this.ignoreNoMoreImages)
				this.noMoreImages = inc != this.options.scrollInc;
			else
				this.ignoreNoMoreImages = false;
			// Add images
			if (inc > 0) {
				this._scroll(-inc, this.noMoreImages)
			}
			// No more images, disable next button
			else {
				if (this.nbInCache >0)
				this._scroll(-this.nbInCache, true);
			
				this._updateButtonStateHandler(this.options.nextElementID, false);
			}
		}
		if (this.options.ajaxHandler)
		this.options.ajaxHandler(this, "after");
	},
  
	_onFailure: function(originalRequest){    
		this.requestIsRunning = false;
	},

	_animDone: function(event){   
		if (this.options.animHandler)
			this.options.animHandler(this.carouselElemID, "after", this.animRunning);
 
		this.animRunning = "none";
		// Call animAfterFinish if exists
		if (this.animAfterFinish)
			this.animAfterFinish(event);
			
		this.fireEvent("onSlideEnd",this.currentIndex);
	},
  
	_updateButtonStateHandler: function(button, state) {
		if (this.options.buttonStateHandler) 
			this.options.buttonStateHandler(button, state);
	},

	_scroll: function(delta, forceDisableNext) {
		this.fireEvent("onScrollStart",this.currentIndex-delta);
		this.animRunning = delta > 0 ? "prev" : "next";
		
		if (this.options.animHandler)
			this.options.animHandler(this.carouselElemID, "before", this.animRunning);
		
		var move = new Fx.Style(this.carouselList, 'left', this.options.animParameters);
		move.start(-1*(this.currentIndex-delta)*this.elementSize)
		
		//var move = new Fx.Scroll(this.carouselClipRegion, this.options.animParameters);
		//move.scrollTo((this.currentIndex-delta)*this.elementSize);
		
		this.currentIndex -= delta;
		this._updateButtonStateHandler(this.options.prevElementID, this.currentIndex != 0);
		
		if (this.options.url && this.noMoreImages == false)
			enable = true;
		else
			enable = (this.currentIndex + this.options.numVisible < this.options.size);
		this._updateButtonStateHandler(this.options.nextElementID, (forceDisableNext ? false : enable));
	},
	
	_getLiElementSize: function() {
		var li = $(this.carouselList.getElementsByTagName("li")[0]);
		this.elementSize = li.getSize().size.x + parseFloat(li.getStyle("margin-left")) + parseFloat(li.getStyle("margin-right"));
	}
});
Carousel.implement(new Events);
