window.addEvent('domready', function() {								 
	currency = Cookie.get("cur");
	if( currency == false ){
		currency=1;
		Cookie.set("cur", currency , {duration: 1}); // default
	}
	var request = new Json.Remote('json/change.js', {
		method: 'get',
		onComplete: function(jsonObj) {
				ChangeObject = jsonObj;
				loadJson();
		}
	}).send();
	setCur();
	$('container_static').remove();
	$('container').setStyle( "display","block");
	
});
lastSort="";
countrySession="ALL";
/*----------------------------setCur()--------------------------------
Role 		=  	set the current currency
Return  	= 	nothing
Arguments 	= 	nothing
----------------------------------------------------------------------------*/
function setCur(){
	$ES('span','cur').each(function(el){				
				el.onclick=function(){
					//all currency set
					$ES('span','cur').each(function(el){
							el.setProperty('class', 'cur');		
					});
					//this currency active
					el.setProperty('class', 'targetCur');
					//change currency
					currency=el.id.substring(3);
					Cookie.set("cur", currency , {duration: 1}); 
					//sort event with new currency.
					sortEvents();
				}
									 });
	//set current currency
	if(currency!=0)
 		$('cur'+currency).setProperty('class', 'targetCur');
}
/*----------------------------initCart()--------------------------------
Role 		=  	init the cart
Return  	= 	nothing
Arguments 	= 	nothing
----------------------------------------------------------------------------*/
/*
var cartContent;
var cookieForm="";
function initCart(){
	cartContent = Cookie.get("CartEvents");  //load cookie data
	if(!cartContent)
		cartContent = "|";
	//var inputEvent = new Element('input',{'type': 'hidden','id': 'orderEvents','name': 'orderEvents','value': '|'}).injectInside($('cartForm'));
	arr_cartContent = cartContent.split('|');
}
*/
/*----------------------------jsonInitComponent()--------------------------------
Role 		=  	init component with json(cart, sort by date)
Return  	= 	nothing
Arguments 	= 	nothing
----------------------------------------------------------------------------*/
function jsonInitComponent(){
	var maxDayStart=new Date(2000,00,01); //one less for month
	var minDayStart=new Date(4000,11,31); //one less for month
	nbMonth=0;
	//json loop
	JsonObject.events.each(function(events) {
		//build cart
		if(bool_firstLoad){
			//loadCartItems();
			/*
			arr_cartContent.each(function(el){
				debug.display( events.ID + ' == '+el + ' 73');
				if( events.ID == el ){
					 cookieForm    += events.ID + '|';
					 //build_cart(events.ID,events.title,events.dayStart);
					 build_cart(events.ID,events.title,events.city);
					 $('orderEvents').value = '|' + cookieForm;
				}
			});
			*/
		}
		//build sort date
		var arr_dayStart = events.dayStart.split('-');
		
		
		arr_dayStart[1]=arr_dayStart[1]-1;
		dayStart = new Date(arr_dayStart[0],arr_dayStart[1],arr_dayStart[2]);
		
		//find the max date start
		if( dayStart.getFullYear() >= maxDayStart.getFullYear() ){ //check if it's a bigger or equal year
			 if( dayStart.getFullYear() > maxDayStart.getFullYear() ) //if it's bigger year we add this date
			 		maxDayStart=dayStart;
			else if( dayStart.getMonth() > maxDayStart.getMonth() ) //if it's an equal year we check the month
					maxDayStart=dayStart;
		}
		//find the min day start
		if( dayStart.getFullYear() <= minDayStart.getFullYear() ){ //check if it's a smaller or equal year
			 if( dayStart.getFullYear() < minDayStart.getFullYear() ) //if it's a smaller year we add this date
			 		minDayStart=dayStart;
			else if( dayStart.getMonth() < minDayStart.getMonth() ) //if it's an equal year we check the month
					minDayStart=dayStart;
		}
	});
	eventYear=minDayStart.getFullYear();
	monthStart=minDayStart.getMonth()+1;
	//find total number of month between dayStart et last dayStart
	for( i = minDayStart.getFullYear() ; i <= maxDayStart.getFullYear() ; i++){ //for each year
		if( i == maxDayStart.getFullYear() && i == minDayStart.getFullYear() ){
			for( j = monthStart ; j <= maxDayStart.getMonth() ; j++) //add all month
				nbMonth++;
		}else if( i == maxDayStart.getFullYear() ){ //if it's the last year
			for( j = 1 ; j <= maxDayStart.getMonth() ; j++) //add all month
				nbMonth++;
		}else if( i == minDayStart.getFullYear() ){ //if it's the first year
					for( j = monthStart ; j <= 12 ; j++) //add all month
						nbMonth++;
				}else { 
					for( j = 1 ; j <= 12 ; j++) //add all month
						nbMonth++;
				}
	}
	MonthsList = new Array("December","January","February","March","April","May","June","July","August","September","October","November","December");
	//init slider
	init_slider();
}
/*----------------------------disableSort()--------------------------------
Role 		=  	give disabled property to each chexckbox of sort list
Return  	= 	nothing
Arguments 	= 	nothing
----------------------------------------------------------------------------*/
function disableSort(){
	sortDiv="";
	arr_lastSort = new Array();
	count_sort=0;
	//find if existing a category alone (only input checked in this category)
	$ES('input','sortMenu').each(function(elinput){
		if(elinput.checked!=false)
			if(sortDiv =="" || sortDiv == elinput.getParent().id) 
				sortDiv = elinput.getParent().id;
			else
				sortDiv="noSort";
	 });
	
	//make disabled every input exept the last groupe of input checked
	$$('.SortDiv').each(function(eldiv){
		if( eldiv.id != lastSort ){
			$ES('input',eldiv.id).each(function(elinput){
					elinput.setProperty('disabled','disabled');
			});
		}
	});
	
	//make not disabled if it's the last category who still alive
	if(sortDiv != "noSort" && sortDiv != ""){
		$ES('input',sortDiv).each(function(elinput){
					elinput.setProperty('disabled','');
			});
	}
	
}
/*----------------------------init_slider()--------------------------------
Role 		=  	init the slider
Return  	= 	nothing
Arguments 	= 	nothing
----------------------------------------------------------------------------*/
var firstMonth = 0 ;
var lastMonth =0;

function init_slider(){
  var mySlide = new Slider($('bg_slider'), $('slider'), {
  	onChange: function(pos){
		
		maxYear=0;
		minYear=0;
		if(pos.minpos<0)
			pos.minpos=0;
		for(i = pos.maxpos + monthStart ; i > 12 ; i = i - 12 ){
			maxYear++;
		}
		for(i = pos.minpos + monthStart ; i > 12 ; i = i - 12 ){
			minYear++;
		}

		//alert(( pos.minpos + monthStart ) % 12);
		firstMonth = ( pos.minpos + monthStart ) % 12 ;
		lastMonth  = ( pos.maxpos + monthStart ) % 12 ;
		if(firstMonth==0)
			firstMonth=12;
		if(lastMonth==0)
			lastMonth=12;
	    $('firstMonth').setHTML(MonthsList[firstMonth]);
		$('firstYear').setHTML(eventYear + minYear);
		$('lastMonth').setHTML(MonthsList[lastMonth]);
		$('lastYear').setHTML(eventYear + maxYear);
		
		if($('slider').offsetLeft < $('slider2').offsetLeft){
			//$('test').setHTML(MonthsList[pos.maxpos%12] + ' ' + (eventYear + maxYear));
	   		/*$('slider').setHTML(firstMonth);
			$('slider2').setHTML(lastMonth);*/
		}else{
			/*$('slider').setHTML(lastMonth);
			$('slider2').setHTML(firstMonth);*/
		}
  	},
  	/*onTick: function(pos){
  	    fx1.custom(pos);
  	},
	onMaxTick: function(pos){
  	    fx2.custom(pos);
  	},*/
  	onComplete :function(pos){
		currentPage=0;//set current page
		if(!bool_firstLoad)
  	    	sortEvents();
  	},
  	steps: nbMonth
  },$('slider2')).set(0);  //use .set(0) to init slider when it's load 
}
/*----------------------------setSort()--------------------------------
Role 		=  	init the array of sort
Return  	= 	nothing
Arguments 	= 	nothing
----------------------------------------------------------------------------*/
arr_sort = new Array(); //to know wich kind of sort we do on json data
arr_type = new Array(); //to know wich type of sort exist
function setSort(){
	//define onclick for btn to navigate between each page
	$('eventsFooterRight').onclick=function(){
		currentPage++;
		sortEvents();
	}
	$('eventsFooterLeft').onclick=function(){
		currentPage--;
		sortEvents();
	}
	
	//define the first region to show
	$$('#region div').each(function(el){
		 $(el).setStyle("display","none");
	});
	$( $('countrySel').value ).setStyle("display","block");
	//when country change
	$('countrySel').addEvent('change', function(){
		if (this.value != 0) {
			currentPage = 0;//set current page
			//delete sort region 
			delete arr_sort[$($('countrySel').value).getProperty('name').substring(4)];
			arr_sort[$($('countrySel').value).getProperty('name').substring(4)] = new Array();
			//show events
			countrySession = $('countrySel').value;
			loadJson();
			//sortEvents();
			
			//hide each region div
			$$('#region div').each(function(el){
				$(el).setStyle("display", "none");
			});
			//delete all checked property in region
			$$('#region input').each(function(el){
				$(el).setProperty("checked", "");
			});
			//show the right region div
			$($('countrySel').value).setStyle("display", "block");
		}
	});

	//Set sort by input checkbox
	$$('.SortDiv').each(function(eldiv){
		nameDiv = eldiv.getProperty('name');
		arr_sort[nameDiv.substring(4)] = new Array();
		arr_type[nameDiv.substring(4)] = eldiv.id;
		
		$ES('input',eldiv.id).each(function(elinput){
			//add event onclick for each input sort
			elinput.addEvent('click', function(){
				currentPage=0;//set current page
				addSort(elinput); //add a param for the sort of events
				lastSort=eldiv.id;//last group sorted
				sortEvents();
				//check if they are sort input checked and disabled in the same time
				//if they are we make this one not disabled
				
				var bool_showChkDis;
				$ES('input',lastSort).each(function(elinput){
					if(bool_showChkDis==undefined || bool_showChkDis){
						if( elinput.checked!=false && elinput.disabled!=false || elinput.checked==false )
								bool_showChkDis=true;
						else{
							bool_showChkDis=false;
						}
					}
				 });
				
				if(bool_showChkDis){
					$ES('input','sortMenu').each(function(elinput){
						if( elinput.checked!=false && elinput.disabled!=false )							  
							elinput.setProperty('disabled','');
					 });
				}
				delete bool_showChkDis;
			});
		});
	});
	//set sort for date element
	arr_sort['date'] = new Array();
	//Popular Search
	/*
	var popularlink = $$( '#popularLinks a'); //get an array of all <a> in popularLinks id parent
	popularlink.each( function( el ) { // start while on each <a>
	  el.addEvent( 'click', function( e ) { // add event
	    var e = new Event( e ).stop(); // stop event
	    loadJson( el.getText(), 'or'); // call search
	  });
	});
	*/
	//Set sort by input search
	//SearchInput=$('search');
	$('searchForm').setProperty('onSubmit', 'return searchEvents()');
			//loadJson(SearchInput.getPrevious().value);


	/*$('clearSearch').addEvent('click', function(){
			JsonObject = MainObject;
			sortEvents();
			$('searchWord').setHTML('');
		});*/
	$ES('.toCart', 'events').each(function(el){
			el.onclick = function(){addCart(this);}
	 });
}
function searchEvents(){
	if($('phrase').value ){
		loadJson($('phrase').value,$('option').value);	
	}
	return false;
}
/*----------------------------addSort(el)--------------------------------
Role 		=   add or dell a new type of sort inside the array
Return  	= 	nothing
Arguments 	= 	el : an html object from sortmenu
----------------------------------------------------------------------------*/
function addSort(el){
	var parent=el;
	var bool_parent=false;
	//find parent div sort
	while(!bool_parent){
		parent=parent.getParent();
		if(parent.getTag()=='div' && parent.getProperty('name').substring(0,4)=='Sort')
				bool_parent=true;
	}
	//add sort in array
	if(arr_sort[parent.getProperty('name').substring(4)][el.name] == undefined)
		arr_sort[parent.getProperty('name').substring(4)][el.name]=el.value;
	else
		delete arr_sort[parent.getProperty('name').substring(4)][el.name];
}
/*----------------------------delCart(ev)--------------------------------
Role 		=   delete an event in cart
Return  	= 	nothing
Arguments 	= 	ev : an html object ( DIV ) with an event inside
----------------------------------------------------------------------------*/
/*
function delCart(ev){
	arr_cart['event'+ev]=false;
	$('order'+ev).remove(); //remove div
	$('orderEvents').value = $('orderEvents').value.replace('|' + ev + '|','|'); //remove id in form
	//remove cookie
	cartContent = cartContent.replace('|' + ev + '|','|');
	Cookie.set("CartEvents", cartContent , 1); 
}
*/
/*----------------------------addCart(ev)--------------------------------
Role 		=   Createa clone of an event and place him in the basket with animation
Return  	= 	nothing
Arguments 	= 	ev : an html object ( DIV ) with an event inside
----------------------------------------------------------------------------*/
//initialize effect for addcart
var dropFx = $('cart').effect('background-color', {wait: false});
/*
arr_cart =new Array(); //to know which events are in the cart
function addCart(ev){
	eventId="event"+ev;
	if( ! arr_cart[eventId] ){ //check if this event already exist
		//creat a clone of an event
		var clone = $(eventId).clone()
					.setStyles($(eventId).getCoordinates()) // this returns an object with left/top/bottom/right, so its perfect
					.setStyles({'opacity': 0.7,'position': 'absolute','overflow':'hidden'})
					.inject(document.body);
					
		//creat an Fx to anim this event		
		var EventChange = new Fx.Styles(clone, {
								duration:500, 
								wait:false,
								onComplete: function(){
									 clone.remove();
									var idClone = clone.id.substring(5);
									var orderTitle = $ES('.drkBlue',clone).getText();
									var orderCity = $ES('.city',clone).getText();
									build_cart(idClone,orderTitle,orderCity);
									$('orderEvents').value +=  idClone + '|';
									cartContent +=  idClone + '|';
									Cookie.set("CartEvents", cartContent , {duration: 1}); 
									dropFx.start('7389AE').chain(dropFx.start.pass('ffffff', dropFx));
								}
							});
		//begin animation of this event
		EventChange.start({
			'top': $ES('div', 'cart').getLast().getTop(),
			'left': $ES('div', 'cart').getLast().getLeft(),
			'height': 75,
			'width': 75
		});
	}
}
function build_cart(idEvent,title,date){
	 var OrderEvent = new Element('div',{'class': 'order','id': 'order' +  idEvent}).inject($('cartContent'));
	 var Event 		= new Element('div',{'class': 'cartTitle'}).setHTML(title).injectInside(OrderEvent);
	 var EventDel 	= new Element('div',{'class': 'delete'}).injectAfter(Event);
	 var DelEvent 	= new Element('input',{'type': 'button', 'value': 'X'}).injectInside(EventDel);
	 DelEvent.onclick=function(){delCart(idEvent);};
	 var EventDate 	= new Element('div',{'class': 'date'}).setHTML( date ).injectAfter(EventDel);
	 arr_cart['event' + idEvent]=true;	
}
*/
/*----------------------------sortEvents()--------------------------------
Role 		=   function to creat a  refine list of div in Events div from json file
Return  	= 	nothing
Arguments 	= 	nothing
----------------------------------------------------------------------------*/
var eventsByPage=10; //nb of events by page
var currentPage=0;//current page of events
var eventCount=0; //nb of events for a search
var string_type=""
var string_type_temp=""
function sortEvents() {
	disableSort();
	$('events').empty();
	//alert(arr_sort.length);
	string_type = '';
	arr_sort.each(function(div){
		if(div != undefined){
			div.each(function(input){
				if(input != undefined)
					string_type_temp+=input;
			});
		}
		if(string_type_temp!="")
			string_type += " && (" + string_type_temp.substring(4) + ")"
		string_type_temp = "";
	});
	if(string_type!="") string_type="true"+string_type;
	else string_type="true";
	
	
	JsonObject.events.each(function(events) {
		
		//check min and max date							
		var bool_date=false;
		var bool_date2=false;
		var eventsDate = events.dayStart.split('-');//explode dayStart
		if( ( eventsDate[0] >= ( eventYear + minYear ) ) && ( eventsDate[0] <= ( eventYear + maxYear ) ) ){ //if it's between or equal max and min year
			if( eventsDate[0] > ( eventYear + minYear ) )
				bool_date=true;
			else if( eventsDate[1] >= firstMonth )
						bool_date=true;
			if( eventsDate[0] < ( eventYear + maxYear ) )
				bool_date2=true;
			else if( eventsDate[1] <= lastMonth )
						bool_date2=true;
		}
		string_date = ( bool_date && bool_date2 );
		
		if( eval(string_type) && string_date ){ //check sort and date
		
			//delete disabled property to each chexckbox of sort list
			arr_type.each(function(value,key){
				
				if(value != undefined){
					if(value=="cat" || value=="audienceType"){
						var values = eval( 'events.' + value ).split(',');
						values.each(function(val){
							$( value + val ).setProperty('disabled','');
						});
					}else
						var v = value + eval( 'events.' + value ) ;
						if (v != null && v != undefined) {
							if ($(v)) {
								$(v).setProperty('disabled', '');
							}
						}
						
				}
			});
			
			if( ( true == ( typeof(events) == 'object' && (currentPage*eventsByPage) <= eventCount && ( ( currentPage*eventsByPage )+eventsByPage ) > eventCount)) ){ //display events by page
				//build this event
				var eventLink='e-' + events.ID + '--' + encodeURIComponent( events.title.replace( / /g , "-" ) ) + '.html';
				eventLink = eventLink.toLowerCase();
				if(events.promo==1)
				str_event='<div class="promoRed">';
				else
				str_event='<div class="promoBlue">';
				
				str_event+='<div class="lightTitle"><h2><a href="'+eventLink+'" class="drkBlue">'+events.title+'</a></h2></div>' ;
				
				if(events.promo==1) str_event+='<div class="logoRed">';
				else str_event += '<div class="logoBlue">';
				str_event += '<div align="center"><a href="'+eventLink+'"><img src="'+ ( events.logo ? events.logo  : IMG_LOGO_DEFAULT ) +'" alt="'+events.title+'" title="'+events.title+'" border="0"></a></div>';
				str_event += '<a href="javascript: addCart( \''+events.ID+'\' );"><img src="http://www.taxevents.com/img/bt_basket.gif" alt="Add To Basket" title="Add To Basket" border="0" height="29" width="120"></a>';
				str_event += '<a href="' + eventLink + '"><img src="http://www.taxevents.com/img/more_info.gif" alt="More Info" title="More Info" border="0" height="29" width="120"></a>';
				str_event += '<p class="price">from: <strong>' + events.cost + '</strong> ' + ChangeObject.change[events.currency].name + '</p>';
				if( currency != 0 && ChangeObject.change[events.currency].name != ChangeObject.change[currency].name   ){ //check if curency session exist and if it's differente
					if( events.currency == '1' )
						str_event+=' <p class="price"><strong>'+Math.round(events.cost*ChangeObject.change[currency].rate)+'</strong> ' + ChangeObject.change[currency].name+'</p>';
					else 
						str_event+=' <p class="price"><strong>'+Math.round(events.cost*ChangeObject.change[events.currency].inverse)+'</strong> '+ChangeObject.change[currency].name+'</p>';
				}
	    		str_event += '</div>'; // END div logoRed/logoBlue
	    		
	    		str_event += '<div class="infoBlue">';
	    		str_event += '<p class="type"><strong>'+events.typeName+'</strong></p>';
	    		str_event += '<p class="date"><strong>'+events.dayStart+'</strong></p>';
	    		str_event += '<p class="timing"><strong>'+events.timing+'</strong></p>';
	    		str_event += '<p class="venue"><strong>'+events.loc+','+events.city+'</strong></p>';
	    		str_event += '<p>'+events.intro+'</p>';
	    		str_event += '<p><strong>Speakers:</strong> '+events.speakerSum+'</p>';
	    		str_event += '<p><strong>Audience:</strong> '+events.audienceDesc+'</p>';
	    		str_event += '</div>'; // END div infoBlue
	    		
				str_event+='<div style="clear: both;"></div>';
				
				if(events.promo==1)
					str_event+='<div class="featuredItemIcon">'+ FEATURED_EVENT+'</div>';
								
				
				str_event += '</div>'; // END div promoRed/promoBlue
				
				// Inject this template
				var el = new Element('div', {'class': 'promo','id': 'event' + events.ID }).setHTML(str_event);
				el.inject($('events'));
				str_event="";
			}
			//increment event counter
			eventCount++;
		}
		
	});
	//add footer for events part
	var nbPage=Math.ceil(eventCount/eventsByPage);
	$('eventsFooterCenter').setStyle('visibility','visible');
	var reelCurrentPage=currentPage+1;
	if( nbPage == 1 || nbPage == 0)
		$('eventsFooterCenter').setStyle('visibility','hidden');
	else
		$('eventsFooterCenter').setStyle('visibility','visible');
	if(reelCurrentPage>1)
		$('eventsFooterLeft').setStyle('visibility','visible');
	else
		$('eventsFooterLeft').setStyle('visibility','hidden');
	if(reelCurrentPage<nbPage)
		$('eventsFooterRight').setStyle('visibility','visible');
	else
		$('eventsFooterRight').setStyle('visibility','hidden');
	$('currentPage').setHTML(reelCurrentPage);
	$('nbPage').setHTML(nbPage);
	
	//show title
	$('title_h2').setHTML('FOUND : ' + eventCount + ' EVENTS' );
	//delete var
	eventCount=0;
	string_type="";
}
/*----------------------------loadJson(varSearch)-------------------------------------------
Role 		=   function to load a json file or call a php file who write json data
Return  	= 	nothing
Arguments 	= 	varSearch : a word to search in DB
---------------------------------------------------------------------------------*/
var bool_firstLoad = true;
function loadJson( varSearch , methode ) {

	if( varSearch == eval("undefined") )
		var url = 'json/json_'+countrySession+'.js';
	else {
		var url = encodeURIComponent( varSearch ) + '_' + methode + '_json_' + countrySession + '.js';
		$('events').empty();
		$$('#eventsFooter div').each(function(el){
				el.setStyle('visibility','hidden'); // hidden
		});
		new Element('img', {'class': 'loading','src': '/img/loading.gif'}).inject($('events')); //show loding gif
	}
	var request = new Json.Remote(url, {
		method: 'post',
		onComplete: function(jsonObj) {
			if( varSearch == eval("undefined") ){
				
				MainObject = jsonObj;
				JsonObject = jsonObj;
			
				if(bool_firstLoad){
					initCart();
					setSort();
					jsonInitComponent();
					bool_firstLoad=false;
				}else{
					$('term').setHTML('');
					$('term').setProperty('display','none');
					jsonInitComponent();
				}
				
			}else{
				
				$('term').setHTML('Search term: ' + varSearch); // show term search
				$('term').setProperty('display','block');
				JsonObject = jsonObj;
				sortEvents();
			}
		}
	}).send();
}
//--------------------------------------class Slider---------------------------------------------------------------------//
/*
Class: Slider
        Creates a slider with two elements: a knob and a container. Returns the values.
 
Note:
        The Slider requires an XHTML doctype.
 
Arguments:
        element - the knob container
        knob - the handle
        options - see Options below
        maxknob - an optional maximum slider handle
 
Options:
        steps - the number of steps for your slider.
        mode - either 'horizontal' or 'vertical'. defaults to horizontal.
        offset - relative offset for knob position. default to 0.
        knobheight - positions the max slider knob
        spread - steps between the knob and maxknob
 
Events:
        onChange - a function to fire when the value changes.
        onComplete - a function to fire when you're done dragging.
        onTick - optionally, you can alter the onTick behavior, for example displaying an effect of the knob moving to the desired position.
                Passes as parameter the new position.
*/
 
var Slider = new Class({
 
        options: {
                onChange: Class.empty,
                onComplete: Class.empty,
                onTick: function(pos){
                        this.knob.setStyle(this.p, pos);
                },
                onMaxTick: function(pos){
				
                        this.maxknob.setStyle(this.p, pos);
                },
                mode: 'horizontal',
                steps: 100,
                knobheight: 16,
                spread: 6,
                offset: 0
        },
 
        initialize: function(el, knob, options, maxknob){
                this.element = $(el);
                this.knob = $(knob);
                this.setOptions(options);
                this.previousChange = -1;
                this.previousEnd = -1;
                this.step = -1;
                if(maxknob != null)
                        this.maxknob = $(maxknob);
                else
                        this.element.addEvent('mousedown', this.clickedElement.bindWithEvent(this));
                var mod, offset;
                switch(this.options.mode){
                        case 'horizontal':
                                this.z = 'x';
                                this.p = 'left';
                                mod = {'x': 'left', 'y': false};
                                offset = 'offsetWidth';
                                break;
                        case 'vertical':
                                this.z = 'y';
                                this.p = 'top';
                                mod = {'x': false, 'y': 'top'};
                                offset = 'offsetHeight';
                }
                this.max = this.element[offset] - this.knob[offset] + (this.options.offset * 2);
                this.half = this.knob[offset]/2;
                this.getPos = this.element['get' + this.p.capitalize()].bind(this.element);
                this.knob.setStyle('position', 'relative').setStyle(this.p, - this.options.offset);
                if(maxknob != null) {
                        this.maxPreviousChange = -1;
                        this.maxPreviousEnd = -1;
                        this.maxstep = this.options.steps;
                        this.maxknob.setStyle('position', 'relative').setStyle(this.p, + this.max).setStyle('bottom', this.options.knobheight);
                }
                var lim = {};
                lim[this.z] = [- this.options.offset, this.max - this.options.offset];
                this.drag = new Drag.Base(this.knob, {
                        limit: lim,
                        modifiers: mod,
                        snap: 0,
                        onStart: function(){
                                this.draggedKnob();
                        }.bind(this),
                        onDrag: function(){
                                this.draggedKnob();
                        }.bind(this),
                        onComplete: function(){
                                this.draggedKnob();
                                this.end();
                        }.bind(this)
                });
                if(maxknob != null) {  
                        this.maxdrag = new Drag.Base(this.maxknob, {
                                limit: lim,
                                modifiers: mod,
                                snap: 0, 
                                onStart: function(){
                                        this.draggedKnob(1);
                                }.bind(this),
                                onDrag: function(){
                                        this.draggedKnob(1);
                                }.bind(this),
                                onComplete: function(){
                                        this.draggedKnob(1);
                                        this.end();
                                }.bind(this)
                        });
                }
                if (this.options.initialize) this.options.initialize.call(this);
        },
 
        /*
        Property: set
                The slider will get the step you pass.
 
        Arguments:
                step - one integer
        */
 
        set: function(firstStep/*,lastStep*/){
                this.firstStep = firstStep.limit(0, this.options.steps);
				//this.lastStep = lastStep.limit(0, this.options.steps);
                this.checkStep();
                this.end();
                this.fireEvent('onTick', this.toPosition(this.firstStep));
				//this.fireEvent('onMaxTick', this.toPosition(this.lastStep));
                return this;
        },
 
        clickedElement: function(event){
                var position = event.page[this.z] - this.getPos() - this.half;
                position = position.limit(-this.options.offset, this.max -this.options.offset);
                this.step = this.toStep(position);
                this.checkStep();
                this.end();
                this.fireEvent('onTick', position);
        },
 
        draggedKnob: function(mx){
                if(mx == null) {
                        this.step = this.toStep(this.drag.value.now[this.z]);
                        this.checkStep();
                }
                else {  
                        this.maxstep = this.toStep(this.maxdrag.value.now[this.z]);
                        this.checkStep(1);
                }
        },
 
        checkStep: function(mx){
                if(mx == null) {
                        if (this.previousChange != this.step){
                                this.previousChange = this.step;
                        }
                }
                else {  
                        if (this.maxPreviousChange != this.maxstep){
                                this.maxPreviousChange = this.maxstep;
                        }
                }
                if(this.maxknob != null) {
                        if(this.step < this.maxstep)
                                this.fireEvent('onChange', { minpos: this.step, maxpos: this.maxstep });
                        else    
                                this.fireEvent('onChange', { minpos: this.maxstep, maxpos: this.step });
                }
                else {  
                        this.fireEvent('onChange', this.step);
                }
        },
 
        end: function(){
                if (this.previousEnd !== this.step || (this.maxknob != null && this.maxPreviousEnd != this.maxstep)){
                        this.previousEnd = this.step;
                        if(this.maxknob != null) {
                                this.maxPreviousEnd = this.maxstep;
                                if(this.step < this.maxstep)
                                        this.fireEvent('onComplete', { minpos: this.step + '', maxpos: this.maxstep + '' });
                                else    
                                        this.fireEvent('onComplete', { minpos: this.maxstep + '', maxpos: this.step + '' });
                        }
                        else {  
                                this.fireEvent('onComplete', this.step + '');
                        }
                }
        },
 
        toStep: function(position){
                return Math.round((position + this.options.offset) / this.max * this.options.steps);
        },
 
        toPosition: function(step){
                return this.max * step / this.options.steps;
        }
 
});
 
Slider.implement(new Events);
Slider.implement(new Options);
