/* custom script goes riiigghht.... 
here ↓ */

jQuery(document).ready(function(){	
		
	
	//main navigation
	jQuery('#heli a').click(function(){	
		window.location.hash = '1::heli::alaska-heli-skiing';
		return false;	
	});
		
	jQuery('#camps a').click(function(){
		window.location.hash = '3::camps::big-mountain-camps';
		return false;
	});
	
	jQuery('#edu a').click(function(){
		window.location.hash = '2::edu::backcountry-education';
		return false;
	});
	
	jQuery('#media a').click(function(){
		window.location.hash = '4::media::media';
		return false;
	});
	
	jQuery('#about a').click(function(){
		window.location.hash = '5::about::about';
		return false;
	});
	
	jQuery('#logo').click(function(){
		window.location.hash = 'home';
		return false;
	});
	
	//high level page grid mouseovers + some other view setup
	setup_view();
	
	
});

var current_hash = false;
var hash_timer;
var view_index = 0;
var pan_top = -1300;
var pan_speed = 1200;
var bounds = [1450,2223,3019,3831];

var init_load = function(){
		
	if(parseFloat(jQuery('#pano').css('left')) < 0){ 

		//refreshed page or legacy browsing
		extra = 0;	
		if(parseFloat(jQuery('#pano').css('left')) < -3200){
			view_index = 5;
		}
	}
	jQuery('html, body').animate({scrollTop:0}, 'slow');
	
	jQuery('#pano').fadeIn('fast').animate({'top':pan_top}, 800, function(){
		hash_timer = window.setTimeout(poll_hash, 300);
		if(window.location.hash == ''){
			jQuery('#ldg').fadeOut('fast', function(){ 	
				jQuery('#content').animate({'opacity':1}).css('visibility','visible');			
			});	
		}
	});
	jQuery('#pf').css('height', jQuery(document).height() - 300 + 'px');
 	
	jQuery('#map-launcher .open').click(function(){

		if(map_launcher_open){
			jQuery(this).addClass('open').removeClass('close');
			jQuery('#map-launcher').animate({'left':-396},'fast');
			launcher_forced_closed = true;
			map_launcher_open = false;
			
		} else {
			var left = (jQuery(window).width() - 396) / 2
			jQuery('#map-launcher').animate({'left':left},'fast');
			jQuery(this).addClass('close').removeClass('open');
			map_launcher_open = true;
		}
		
	});
	
	jQuery('#map-launcher .close').click(function(){

		if(map_launcher_open){
			jQuery(this).addClass('open').removeClass('close');
			jQuery('#map-launcher').animate({'left':-396},'fast');
			launcher_forced_closed = true;
			map_launcher_open = false;
		
		} else {
			
			var left = (jQuery(window).width() - 396) / 2
			jQuery('#map-launcher').animate({'left':left},'fast');
			jQuery(this).addClass('close').removeClass('open');
			map_launcher_open = true;
			
		}
		
	});
	
	jQuery('#lr').mouseover(function(){
		l_pan_dir = -1;
		l_pan_speed = 4;
		pan_map();
	}).mouseout(function(){
		window.clearTimeout(l_pan_timer);
	}).mousemove(function(evt){
		l_pan_speed = 4 + (evt.clientX - jQuery(this).offset().left) / 5;
	});
	
	jQuery('#ll').mouseover(function(){
		l_pan_dir = 1;
		l_pan_speed = 4;
		pan_map();
	}).mouseout(function(){
		window.clearTimeout(l_pan_timer);
	}).mousemove(function(evt){
		l_pan_speed = 4 + (evt.clientX-50) * -1 / 5;
	})

	
}

jQuery(window).resize(function(){
	//return;
	resize_view();
	
}).scroll(function(){
	
		var scroll = jQuery(window).scrollTop();
		
		if(scroll > 280 && !map_launcher_open && view_index >= 0 && !terrain_map_open && !launcher_forced_closed){
			var left = (jQuery(window).width() - 380) / 2
			jQuery('#map-launcher').animate({'left':left},'fast');
			jQuery('#map-launcher .open').addClass('close').removeClass('open');
			map_launcher_open = true;
		}
		
		if(scroll == 0){
			launcher_forced_closed = false;
		}
		
		/*if(scroll <= 250 && map_launcher_open){
			jQuery('#map-launcher').animate({'left':-396},'fast').fadeIn();
			jQuery('#map-launcher .close').addClass('open').removeClass('close');
			map_launcher_open = false;
		}*/
		
		jQuery('#terrain-map').css({'top':scroll});
		jQuery('.m-screen').css({'top':scroll});
		/*if(view_index < 0)
			return;
		var scroll = jQuery(window).scrollTop();
		var extra = 0;
		if(view_index == 0){
			var vpw = jQuery(window).width();
			extra = vpw - 1100;
		}
		if(extra > 240) extra = 240;
 		var top = (pan_top + extra) - (scroll*0.5);
		//if(top < 5) top = 5;
		//console.log(top);
		jQuery('#pano').css({'top':top});
	
*/

});

var map_launcher_open = false;
var terrain_map_open = false;
var launcher_forced_closed = false;
var launch_terrain_map = function(){
	
	terrain_map_open = true;
	jQuery('#terrain-map').fadeIn('fast');	
	jQuery('#map-launcher').animate({'left':-396},'fast');
	jQuery('#map-launcher .open').addClass('close').removeClass('open');
	map_launcher_open = false;
	
	jQuery('#earth').html('');
	
	var center = new google.maps.LatLng(61.127274,'-146.344617');
	
	  var myOptions = {
	    zoom: 9,
	    center: center,
	    mapTypeId: google.maps.MapTypeId.TERRAIN
	  }
	  map = new google.maps.Map(document.getElementById("earth"), myOptions);
	  RemoteCall.handlers = {
		onData:function(data){
			place_map_markers(data.zones);
		},
		onError:function(er){
			alert(er);
		}
	 }	
	 RemoteCall.make('terrain_map','get_points','{}');
		
}

var markers = [];
var place_map_markers = function(markers){
	for(var m = 0; m < markers.length; m++){
		 var marker = new google.maps.Marker({
		 	position:new google.maps.LatLng(markers[m].lat,markers[m].lng),
		 	map: map,
			data: markers[m],
			icon: 'http://sites.alleki.com/alaskahelicopterskiing.com/images/web/terrain-marker.png'
	  	});
	
	  	//markers.push(markers[m]);
		google.maps.event.addListener(marker, 'click', function(event) {
			var more_images = '';
			if(this.data.image2) more_images += '<a href="http://c218823.r23.cf1.rackcdn.com/'+this.data.image2+'" rel="prettyPhoto['+this.data.id+']"><p>View more images of this region...</p><img src="http://c218823.r23.cf1.rackcdn.com/'+this.data.image2+'" style="display:none" /></a>';		 
			if(this.data.image3) more_images += '<a href="http://c218823.r23.cf1.rackcdn.com/'+this.data.image3+'" rel="prettyPhoto['+this.data.id+']"><img src="http://c218823.r23.cf1.rackcdn.com/'+this.data.image3+'" style="display:none" /></a>';		 
			if(this.data.image4) more_images += '<a href="http://c218823.r23.cf1.rackcdn.com/'+this.data.image4+'" rel="prettyPhoto['+this.data.id+']"><img src="http://c218823.r23.cf1.rackcdn.com/'+this.data.image4+'" style="display:none" /></a>';
			Modal.launch_text('<h3>' + this.data.region + ': ' + this.data.name + '</h3><a href="http://c218823.r23.cf1.rackcdn.com/'+this.data.image+'" rel="prettyPhoto['+this.data.id+']"><img src="http://c218823.r23.cf1.rackcdn.com/'+this.data.image+'" style="height:500px;float:left;margin-right:15px;" /></a><p>('+this.data.elevation+' ft) ' + this.data.description + '</p>'+more_images, 900, 550, 25);	
		 	jQuery("a[rel^='prettyPhoto']").prettyPhoto({
				social_tools: '',
				show_title: false,
				callback:function(){
					Modal.close();
					//window.location.hash = '';
				}
			});
		});
	}
}

var close_terrain_map = function(){
	
	jQuery('#earth').html('');
	jQuery('#terrain-map').fadeOut('fast');
	terrain_map_open = false;
}

var pan_to_view = function(i, id, to_load){
	
		jQuery('#galleria').html('&nbsp;').hide();
		jQuery('#ga-holder').hide();
		//update hashtag
		jQuery('#content').animate({'opacity':0}, function(){
		jQuery('#ldg').fadeIn('fast');
		jQuery('#header .menu li a').removeClass('selected');
		jQuery('#'+id + ' a').addClass('selected');
		view_index = i;
		
		var vpw = jQuery(window).width();
		if(i == 5){	
			pan_top = -1300;
			jQuery('#pano').animate({'left':(5696-vpw)*-1,'top':pan_top},pan_speed,function(){
				load_page_content(to_load);	
			});
			return;
		}
	
		if(i > 0){
			pan_top = -1300;
			var left_bound = bounds[i-1];
			var left_offset = (vpw-1024) / 2;		
			var pan_left = (left_bound - left_offset) * -1;
			jQuery('#pano').animate({'left':pan_left,'top':pan_top},pan_speed, function(){
				load_page_content(to_load);
			});
			return;
		}
	
		if(i == 0){
			pan_top = -1300;
			jQuery('#pano').animate({'left':0,'top':pan_top},pan_speed,function(){
				load_page_content(to_load);	
			});
			return;
		}

	});	
}

var resize_view = function(){
	var vpw = jQuery(window).width();
	if(view_index == 5){	
		jQuery('#pano').css({'left':(5696-vpw)*-1});
		return;
	}
	
	if(view_index > 0){
	
		var left_bound = bounds[view_index-1];
		var left_offset = (vpw-1024) / 2;		
		var pan_left = (left_bound - left_offset) * -1;
	
		jQuery('#pano').css({'left':pan_left,'top':pan_top});
	}
	var left = (jQuery(window).width() - 860) / 2;
	jQuery('#ga-holder').css({'left':left});
	
	var left = (jQuery(window).width() - 380) / 2;
	jQuery('#map-launcher').css({'left':left});
	
}

var load_page_content = function(address, subpage){
	jQuery('html, body').animate({scrollTop:0}, 'slow');
	RemoteViewLoader.handlers = {

		onData:function(html){
			
			//load html content and setup any mouseovers as necessary.
			jQuery('#content').html(html);
			
			if(subpage){
				view_index = -1;
				//get the inner content height by creating a clone
				var clone = jQuery('.layout').clone().attr('id','gh').css({'position':'absolute','visibility':'hidden'});
				jQuery('body').append(clone);
				var height = jQuery('#gh').height() + 150;
				jQuery('#gh').remove();
				jQuery('#pf').animate({'height':height+500});
				jQuery('#content').animate({'height':height + 100});
				
				//calcluate new top for pano image
			
				jQuery('#pano').animate({'top':pan_top+height-700});
				jQuery('#map-launcher').fadeOut();
			} else {
				jQuery('#pf').css('height', '1300px');
			}
			
			//set up galleria if media page
			if(view_index == 4){	
				load_photos();	
			}
			
			jQuery('#ldg').fadeOut('fast', function(){
				jQuery('#content').animate({'opacity':1});
				setup_view();
			})
		},
		onError:function(er){
			alert(er);
		}
	}
	RemoteViewLoader.load('content_loader','go', new Array(address));
	
}

var setup_view = function(){
	
	jQuery('#map-launcher').animate({'left':-396},'fast').fadeIn();
	jQuery('#map-launcher .close').addClass('open').removeClass('close');
	map_launcher_open = false;
	
	/*if(document.getElementById('v')){
		var flashvars = {
			'file':               '',
		    'autostart':          'false',
			'searchbar': 'false',
			'width': 576,
			'height': 323,
			'file': 'http://c218823.r23.cf1.rackcdn.com/h2opromo.flv',
			'image': 'http://sites.alleki.com/alaskahelicopterskiing.com/images/web/hero-video-still2.jpg',
			'frontcolor': '0xDDDDDD',
			'lightcolor': '0xEEEEEE',
			'backcolor': '0x000000',
			'icons': '0'
	    };

	   var params = {
	      'allowfullscreen':    'true',
	      'allowscriptaccess':  'always',
	      'wmode':              'transparent'
	   };

	   var attributes = {
	      'id':                 'player',
	      'name':               'player'
	   };
	
	   swfobject.embedSWF('//www.alleki.com/flash/player.swf', 'v', '576', '323', '9', 'false', flashvars, params, attributes);
	}
	
	*/
	
	jQuery('.sp').mouseover(function(){
		
		jQuery(this).css('background','rgba(255,255,255,0.2)');
		var imgs = jQuery(this).children('img');
		jQuery(imgs[1]).fadeOut();
		
	}).mouseout(function(e){
		
		//verify we're actually off the thing with mouse coordinates
		var left = jQuery(this).offset().left;
		var top = jQuery(this).offset().top;
		var right = left + jQuery(this).width();
		var bottom = top + jQuery(this).height();
		if(e.pageY < top || e.pageY > (bottom-10) || e.pageX < left || e.pageX > right){
			jQuery(this).css('background','rgba(255,255,255,0.1)');
			var imgs = jQuery(this).children('img');
			jQuery(imgs[1]).fadeIn();
		}
		
	}).click(function(){
		window.location.hash = 'sp::' + jQuery(this).attr('id');
	});
	
	jQuery('.sp a').click(function(){ window.location.hash = 'sp::' + jQuery(this).parent().parent().attr('id'); return false; });
		
	jQuery('.right .menu a').click(function(){
		var refs = jQuery(this).attr('href').split('/');
		var hash = refs[refs.length-1];
		window.location.hash = 'sp::' + hash;
		return false;
	});
	
	if(typeof jQuery("a[rel^='prettyPhoto']").prettyPhoto != 'undefined'){ 
		jQuery("a[rel^='prettyPhoto']").prettyPhoto({
			social_tools: '',
			show_title: false,
			callback:function(){
				Modal.close();
				////window.location.hash = '';
			}
		});
	}
	
	jQuery('.backtotop').click(function(){
	    jQuery('html, body').animate({scrollTop:0}, 'slow');
		return false;
	});
	
	//forms
	jQuery('input,textarea').focus(function(){	
		jQuery(this).addClass('focused');
		if(jQuery(this).val() == jQuery(this).attr('rel')){
			jQuery(this).val('');
		} 
	}).blur(function(){
		jQuery(this).removeClass('focused');
		if(jQuery(this).val() == ''){
			jQuery(this).val(jQuery(this).attr('rel'));
		}
	});
	jQuery('#subscribe').submit(function(){
		
		var email = jQuery('.mail-signup input:first').val().toString();
		var valid =  /^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
		if(!email.match(valid)){
			alert('Please enter a valid email address...');
			return false;
		}
		jQuery('.mail-signup p:first').html('Signing you up...');
		RemoteCall.handlers = {
			onData:function(d){
				jQuery('.mail-signup p:first').html('You\'re all signed up!');
				jQuery('#subscribe').fadeOut('fast');
			},
			onError:function(er){
				alert(er);
			}
		}
		RemoteCall.make('contact_forms','mail_signup','{"email":"'+email+'","mailing_list_id":"767305468"}');
		return false;
	});
}

var ph_tab_switch = function(w){
	if(w == 0){
		jQuery('#video-gallery').fadeOut();
		jQuery('#ga-holder').fadeIn();
		jQuery('#tabp').attr('class','selected');
		jQuery('#tabv').attr('class','');
	} else {
		jQuery('#ga-holder').fadeOut();
		jQuery('#video-gallery').html('<br /><p>Loading videos...</p>').fadeIn();	
		jQuery('#tabp').attr('class','');
		jQuery('#tabv').attr('class','selected');
		RemoteCall.handlers = {
			onData:function(data){
				jQuery('#video-gallery').html('');
				for(var v = 0; v < data.videos.length; v++){
					jQuery('#video-gallery').append('<a class="vt" href="'+data.videos[v].link+'" rel="prettyPhoto[video]" title=""><img src="'+data.videos[v].thumbnail.url+'" alt="'+data.videos[v].title+'" /><span>'+data.videos[v].title+'</span>');
				}
				jQuery("a[rel^='prettyPhoto']").prettyPhoto({
					social_tools: '',
					callback:function(){
						Modal.close();
						//window.location.hash = '';
					}
				});
			},
			onError:function(er){
				Modal.launch_text(er);
			}
		}
		RemoteCall.make("youtube_data","uploads",'{"user":"h2oguides"}');
	}
}

var poll_hash = function(){
	var hash = window.location.hash.replace('#','');
	if(hash.indexOf('pretty') >= 0){
		poll_timer = window.setTimeout(poll_hash, 100);
		return;
	}
	if(hash != current_hash){
		current_hash = hash;
		var args = hash.split('::');
		if(args.length == 3){
			jQuery('#content').animate({'height':950});
			pan_to_view(args[0], args[1], args[2]);
		} else if(args.length == 2) {
			//subpage routine
			jQuery('#content').animate({'opacity':0}, function(){
				load_page_content(args[1], true);
			});
			
		} else {
			//likely to homepage
			jQuery('#content').animate({'height':950});
			pan_to_view(0,'logo','home');
		}
	}
	poll_timer = window.setTimeout(poll_hash, 100);
}

var seats_selected = function(form){
	var selected = false;
	for(var e = 0; e < form.elements.length; e++){
		
		if(form.elements[e].selectedIndex > 0){
			selected = true;
		}
		
	}
	
	if(!selected){
		Modal.launch_text('<h3>Please select seats before continuing.');
		return false;
	}
	return true;
}

var load_photos = function(){
	
		RemoteCall.handlers = {
			onData:function(data){
				photos = [];
				for(var p = 0; p < data.photos.length; p++){
					photos.push({
						image: 'http://c218823.r23.cf1.rackcdn.com/'+data.photos[p]['file_name'],
						thumb: 'http://c218823.r23.cf1.rackcdn.com/square_'+data.photos[p]['file_name'],
				        big: 'http://c218823.r23.cf1.rackcdn.com/'+data.photos[p]['file_name'],
				        title: '',
				        description: data.photos[p].caption,
				        link: false
					});
				}
				jQuery('#galleria').galleria({
					data_source: photos,
					width:860,
				    height:500
				});
			},
			onError:function(er){
				alert(er);
			}
		}
		
		var left = (jQuery(window).width() - 860) / 2;
		jQuery('#ga-holder').css({'left':left}).fadeIn('fast');
		jQuery('#galleria').html('<p style="color:#FFF;">Loading photos....</p>').fadeIn('fast');
		RemoteCall.make('photo_gallery','photo_json','{}');
	
}

var l_pan_speed = 0;
var l_pan_dir = -1;
var l_pan_timer = null;

var pan_map = function(){
	var left = jQuery('#pano').offset().left;
		left += (l_pan_speed * l_pan_dir);
	
	if(l_pan_dir == -1){
		var vpw = jQuery(window).width();
		var min = (5696-vpw)*-1;
		if(left <= min){
			window.clearTimeout(l_pan_timer);
			return false;
		}
	} else {
		if(left > 0){
			window.clearTimeout(l_pan_timer);
			return false;
		}
	}
	jQuery('#pano').css('left',left);
	//console.log('pan: ' + left + ' : ' + l_pan_dir + ' : ' + l_pan_speed);	
	l_pan_timer = window.setTimeout(pan_map,10);
}

/* 	
	a few core workers that make life nicer/mvc friendly...
		
	Modal object - launches a nice looking modal window and writes to it via: 
	
	launch_text(string) - populates html(string) via jQuery
	launch(address) - address matches an Alleki web publisher page address and renders that content (great for CMS powered help/tooltips!)
	launch_uri(uri) - a uri pattern useful if you want to render out of a front end application. ie 'users/login' renders a login form

*/
/* 
	modal window object 
*/
var Modal = {
	launch:function(address, width, height, top, xoffset, yoffset){	
		if(!width) width = 450;
		if(!height) height = 300;
		if(!top) top = 150;
		jQuery('body').append('<div class="m-screen"> </div><div class="modal" id="info-window" style="z-index:2000;"><div><img src="'+WEB_HOME+'images/loader-trans.gif" /></div></div>');
		var scroll = jQuery(document).scrollTop();
		var left = (jQuery(window).width() - width) / 2;
		jQuery('#info-window').css({"top":top + scroll,"left":left});
		jQuery('#info-window div').css({"width":width, "height":height});
		jQuery('.m-screen').click(function(){ Modal.close(); }).css({'height':jQuery(window).height(),'top':scroll});
		RemoteViewLoader.handlers = {
			onData:function(string){
				jQuery('#info-window div').html('<a href="javascript:Modal.close();" class="m-close"><span>close</span></a>' + string);
			},
			onError:function(){
				jQuery('#info-window div').html('<h1>ERROR:</h1><p>' + err + '</p>');
			}
		}
		RemoteViewLoader.load("modal_content","by_address",new Array(address));
		return false;
	},
	launch_text:function(text, width, height, top, xoffset, yoffset){
		
		if(!width) width = 450;
		if(!height) height = 300;
		if(!top) top = 150;
		jQuery('body').append('<div class="m-screen"> </div><div class="modal" id="info-window"><div><a href="javascript:Modal.close();" class="m-close"><span>close</span></a>'+text+'</div>');
		var scroll = jQuery(document).scrollTop();
		var left = (jQuery(window).width() - width) / 2;
		jQuery('#info-window').css({"top":top + scroll,"left":left});
		jQuery('#info-window div').css({"width":width, "height":height});
		jQuery('.m-screen').click(function(){ Modal.close(); }).css({'height':jQuery(window).height(),'top':scroll});
	},
	launch_uri:function(uri, width, height, top){
		if(!width) width = 450;
		if(!height) height = 300;
		if(!top) top = 150;
		jQuery('body').append('<div class="m-screen"> </div><div class="modal" id="info-window" style="z-index:2000;"><div><img src="'+WEB_HOME+'images/loader-trans.gif" /></div></div>');
		var scroll = jQuery(document).scrollTop();
		var left = (jQuery(window).width() - width) / 2;
		jQuery('#info-window').css({"top":top + scroll,"left":left});
		jQuery('#info-window div').css({"width":width, "height":height});
		jQuery('.m-screen').click(function(){ Modal.close(); }).css({'height':jQuery(window).height(),'top':scroll});
		var handlers = {
			onData:function(string){
				jQuery('#info-window div').html('<a href="javascript:Modal.close();" class="m-close"><span>close</span></a>' + string);
			},
			onError:function(){
				jQuery('#info-window div').html('<h1>ERROR:</h1><p>' + err + '</p>');
			}
		}
		var req = new Request(handlers);
			req.send(uri);
		return false;
	},
	close:function(){
		jQuery('#info-window').fadeOut().remove();
		jQuery('.m-screen').remove();
	}
	
}




/* 
	ajax call wraper takes, controller, action and json object.  
*/
var RemoteCall = {
	handlers:null,
	make:function(controller, action, object, string){
		if(!string) string = true;
		var req = new Request(RemoteCall.handlers, string);
			req.send(WEB_HOME + "remotecall/?remote=1&name="+controller+"&action="+action+"&obj=" + object);
	}
}

var RemoteViewLoader = {
	handlers:null,
	load:function(controller, action, args){
		if(!args) args = new Array();
		var req = new Request(RemoteViewLoader.handlers, false);
		var arg  = args ? args.join("/") : '';
			req.send(WEB_HOME + controller + "/" + action + "/" + arg);
	}
}

/*
	AJAX 2004 style! 
*/
function Request(handlers, evaluate){
  this.onData = handlers.onData;
  this.onError = handlers.onError ? handlers.onError : false;
  this.onLoading = handlers.onLoading ? handlers.onLoading : false;
  this.evaluate = evaluate;
  this.lastRequest = ""; 
  var xmlhttp=false;
  var This = this; // < anyone else remember that scoping nightmare??
  try { 
  	xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
 	} catch (e) {
 		 try {
  	 		xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
  		  } catch (E) {
   			xmlhttp = false;
  		 }
 	}
   if (!xmlhttp && typeof XMLHttpRequest!='undefined') {
  		xmlhttp = new XMLHttpRequest();
    }
   this.stateChange = function( ){
		if ( xmlhttp.readyState == 4) {	
        	if (xmlhttp.status == 200) {
		    	var response = (xmlhttp.responseText) ? xmlhttp.responseText : ""; 
				if(This.evaluate){
					var result;
					var str = 'result = ' + response + ';';
					try{
						eval(str);
					}catch(e){
						This.onError(response);		
					}
					response = result;					
				}
				This.onData(response, This);
       		} else {
            	var e = xmlhttp.statusText;
				if(This.onError) This.onError(e, This);
        	}
	   }
   } 
   this.send = function( url, requestHeaders ) {
	  if(xmlhttp){		
	    	if(This.onLoading) This.onLoading();
  			xmlhttp.open("POST", url , true);
			xmlhttp.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
 			xmlhttp.onreadystatechange = This.stateChange;
			This.lastRequest = url;
			xmlhttp.send(null);
	   }else{
		   if(This.onError) This.onError("Sorry, your browser does not support remote requests.");
	   }
   }
}

/*	
	simple keyboard event observer object (supports: 'shift','ctl','up','down','left','right','tab')
	
	KeyEventObservers.add('dn', function(){
		console.log('Down key pressed!');
	});
	
*/
var KeyEventObservers = {
	list:null,
	add:function(key, handler){ 
		if(KeyEventObservers.list == null){
			 KeyEventObservers.list = new Object();
			 addWindowEventListener('keydown',KeyEventObservers.onkeydown, false);
			 addWindowEventListener('keyup',KeyEventObservers.onkeyup, false);
		}
		if(!KeyEventObservers.list[key]) KeyEventObservers.list[key] = new Array();
		KeyEventObservers.list[key].push(handler);			
	},
	onkeydown:function(e){
		if( ! KeyEventObservers.list[KeyMap.lookup(e.keyCode)]) return true;
		var observers = KeyEventObservers.list[KeyMap.lookup(e.keyCode)];
	    for(var o = 0; o < observers.length; o++){
			if(observers[o].down) observers[o].down(e);
		}
		return true;
	},
   	onkeyup:function(e){ 
		if( ! KeyEventObservers.list[KeyMap.lookup(e.keyCode)]) return true;
		var observers = KeyEventObservers.list[KeyMap.lookup(e.keyCode)];
	    for(var o = 0; o < observers.length; o++){
			if(observers[o].up) observers[o].up(e);
		}
		return true;
	}
}

var KeyMap = {
	names:['shift','ctl','up','down','left','right','tab'],
	//note: safari shift, ctl, and alt don't fire events!
	safari:[16,17,38,40,37,39,9],
	moz:[16,17,38,40,37,39,9],
	ie:[16,17,38,40,37,39,9],
	mac:[16,224,38,40,37,39,9],
	lookup:function(test){	
		var code = internet_explorer ? KeyMap.ie : KeyMap.moz;
		if(macintosh) code = KeyMap.mac;
		if(safari) code = KeyMap.safari;
		for(var i = 0; i < code.length; i++){
			if(code[i] == test)
				return KeyMap.names[i];
		}
		return "all";
	}
}

function addWindowEventListener(eventName, callback, bubble){
	if(window.addEventListener){          
		window.addEventListener(eventName, callback, bubble);
	} else {
		document.attachEvent('on' + eventName, callback);
	}                                                  
}


/*
	simple cookies object... 
	
	Cookies.set('key','value');
	
*/

var Cookies = {
	set:function(name, value, expires, path, domain, secure) {
  		var xtime = new Date(expires);
  		var curCookie = name + "=" + escape(value) +
      		((expires) ? "; expires=" + xtime.getUTCDate() : "") +
      		((path) ? "; path=" + path : "") +
      		((domain) ? "; domain=" + domain : "") +
      		((secure) ? "; secure" : "");
 		 document.cookie = curCookie;
	},
	get:function(name) {
  		var dc = document.cookie;
  		var prefix = name + "=";
  		var begin = dc.indexOf("; " + prefix);
  		if (begin == -1) {
   		 begin = dc.indexOf(prefix);
   		 if (begin != 0) return null;
  		} else
    		begin += 2;
  		var end = document.cookie.indexOf(";", begin);
  		if (end == -1)
    		end = dc.length;
  		return unescape(dc.substring(begin + prefix.length, end));
	},
	remove:function(name, path, domain) {
  		if (this.get(name)) {
    		document.cookie = name + "=" +
    		((path) ? "; path=" + path : "") +
    		((domain) ? "; domain=" + domain : "") +
    		"; expires=Thu, 01-Jan-70 00:00:01 GMT";
  		}
	},
	fixDate:function(date) {
  		var base = new Date(0);
  		var skew = base.getTime();
  		if (skew > 0)
    		date.setTime(date.getTime() - skew);
	}
}


var loadAllekiScriptResource = function(resource){
	
	jQuery('body').append('<script type="text/javascript" src="//www.alleki.com/javascript/'+resource+'.js"> </script>');
	
}




