/**
 * jQuery iPad App plugin
 * Designed to handle standard UI functionality on the iPad platform
 * @name jquery.ipad-app-0.1.js
 * @author Immix Productions
 * @version 0.1
 * @date January 29th 2011
 * @category jQuery plugin
 * @copyright (c) 2011 Immix Productions
 */

(function($) {
	$.fn.extend({
		iPadApp: function(options) {
			
			var obj = null;
			var screen_width = 0;
			var finger_moved = false;
			var current_screen = 0;
			var screen_count = 0;
			var fingerCount = 0;
			var scrollY = 0;
			var startX = 0;
			var startY = 0;
			var curX = 0;
			var curY = 0;
			var deltaX = 0;
			var deltaY = 0;
			var horzDiff = 0;
			var vertDiff = 0;
			var swipeLength = 0;
			var swipeAngle = null;
			var swipeDirection = null;
			var is_ipad = false;
			var loading_timeout = false;
			
			
			var defaults = {
				width:1024,
				height:768,
				autosize: true, // resize elements to fit screen
				elastic: true, // elastic effect when attempting to slide past first or last screen
				screen_class:'screen',
				main_menu_id:false, // (requires: wrap_id, loading_image) if set the main menu is setup so that links will not fully reload the page, ipad app style
				main_menu_overlay:false, // pre alpha				
				main_menu_hover_in:false, // callbacks for main_menu rollovers
				main_menu_hover_out:false, // callbacks for main_menu rollovers 										 
				loading_image:false, // (requires: loading_image_width, loading_image_height) must be a valid transparent gif
				loading_image_width:false, 
				loading_image_height:false,
				wrap_id:false, // disables overscrolling
				home_button:false,
				mask_id:'mask',
				banner_id:false,
				easing:'circEaseOut',				
				swipe_length:70,
				scrolling:false, // pre alpha. Makes your iPad cry
				nav_buttons_img:false, 	// false if no nav buttons, or path to sprite image
				nav_align:'right', // left, right or center
				nav_button_size:15, // in pixels
				nav_button_spacing:6,
				nav_top:false, 					// top coordinates for navigation buttons. false or pixels
				nav_left:false,	 				// left coordinates for navigation buttons false or pixels
				nav_bottom: '13px', 		// bottom coordinates for navigation buttons false or pixels
				nav_right: '17px' 		  // right coordinates for navigation buttons false or pixels
			};						
			var options = $.extend(defaults, options);
			
			return this.each(function() {
				obj = $(this);
				
				obj.hide();
				
				// setup home button
				if (options['home_button']) {
					$(options['home_button']).bind('touchend', function(){
						change_screen(0);
					});
					$(options['home_button']).click(function(){
						change_screen(0);
					});
				}
				
				$('#' + options['wrap_id']).bind("touchstart", function(event) { event.preventDefault(); return false; });
				$('#' + options['wrap_id']).bind("touchmove", function(event) { event.preventDefault(); finger_moved = true; return false; });	
				$('#' + options['wrap_id']).bind("touchend", function(event) { event.preventDefault(); return false; });
				
				// setup nav
				if (options['nav_buttons_img'] != false)
					init_navigation();
					
				// setup screens
				init_screens();
				
				if (options['main_menu_id'] && options['wrap_id']) {
					init_main_menu();
				}
				
				if(options['main_menu_overlay']) {
					$('#' + options['wrap_id']).get(0).addEventListener("touchmove", main_menu_rollover, false);
				}			
				
				obj.show();
			});
			
			function init_navigation() {				
		  	$("#" + options['mask_id']).append('<div class="nav_wrap"></div>');
		  	$("#" + options['mask_id']).find(".nav_wrap").css({
		  		'position': 'absolute',
		  		'width': options['width'] + 'px',
		  		'height': options['nav_button_size'] + 'px',
		  		'z-index': '700',
					'text-align':options['nav_align']
		  	});
				
				$("#" + options['mask_id']).find(".nav_wrap").append('<div class="nav"></div>');
		  	$("#" + options['mask_id']).find(".nav").css({
		  		'position': 'relative',
					'left':'-' + options['nav_button_spacing'] + 'px',
		  		'height': options['nav_button_size'] + 'px',
		  		'z-index': '700',
					'margin':'0 auto'
		  	});
		  	
				if (!options['nav_align'] != 'center') {
					if (options['nav_left']) 
						$("#" + options['mask_id']).find(".nav_wrap").css("left", options['nav_left']);
					if (options['nav_right']) 
						$("#" + options['mask_id']).find(".nav_wrap").css("right", options['nav_right']);
				}
				
				if (options['nav_top']) 
					$("#" + options['mask_id']).find(".nav_wrap").css("top", options['nav_top']);
				if (options['nav_bottom']) 
					$("#" + options['mask_id']).find(".nav_wrap").css("bottom", options['nav_bottom']);
		  }
			
			function main_menu_rollover(event) {		
				var tmpX = event.touches[0].pageX;
				var tmpY = event.touches[0].pageY;
				
				var tmp_pos = $("#" + options['main_menu_id']).offset();
				var tmp_width = $("#" + options['main_menu_id']).outerWidth();
				var tmp_height = $("#" + options['main_menu_id']).outerHeight();
				
				if(tmpX >= tmp_pos.left && tmpX <= (tmp_pos.left + tmp_width) && tmpY >= tmp_pos.top && tmpY <= (tmp_pos.top + tmp_height)) {					
				
					$("#" + options['main_menu_id']).find("a").each(function(){
						tmp_pos = $(this).offset();
						tmp_width = $(this).outerWidth();
						tmp_height = $(this).outerHeight();		
						
						if(tmpX >= tmp_pos.left && tmpX <= (tmp_pos.left + tmp_width) && tmpY >= tmp_pos.top && tmpY <= (tmp_pos.top + tmp_height)) {		
							$(this).trigger("touchmove");

							//$(this).siblings().trigger("touchend");
							$("#" + options['main_menu_id']).find("a").not(this).each(function() {
								options['main_menu_hover_out'].apply($(this));
							});
							return;
						}
					});
				}
			}
			
			function init_main_menu() {
				// loading animation
				if (options['loading_image'] && $("body").find("#ipad_loading").length <= 0) {
			  	$("body").append('<div id="ipad_loading" style="display: none;"><img src="' + options['loading_image'] + '" /></div>');
			  	$("body").find("#ipad_loading").css({
			  		'position': 'absolute',
			  		'top': $("#" + options['mask_id']).offset().top + 'px',
			  		'left': $("#" + options['mask_id']).offset().left + 'px',
			  		'width': $("#" + options['mask_id']).width() + 'px',
			  		'height': $("#" + options['mask_id']).height() + 'px',
			  		'z-index': '1000'
			  	}).find('img').hide().load(function(){
			  		$(this).css({
			  			'position': 'absolute',
			  			'display': 'block',
			  			'top': (($("#" + options['mask_id']).height() / 2) - (options['loading_image_height'] / 2)) + 'px',
			  			'left': (($("#" + options['mask_id']).width() / 2) - (options['loading_image_width'] / 2)) + 'px'
			  		}).show();
			  	});
			  } else if($("body").find("#ipad_loading").length == 1) {
					$("body").find("#ipad_loading").show().css({
			  		'top': $("#" + options['mask_id']).offset().top + 'px',
			  		'left': $("#" + options['mask_id']).offset().left + 'px',
			  		'width': $("#" + options['mask_id']).width() + 'px',
			  		'height': $("#" + options['mask_id']).height() + 'px',
						'opacity':1
					});
				}
				
				$("#" + options['main_menu_id']).find("a").each(function(){
					$(this).bind("touchstart", function(event) {											
						event.preventDefault();
						finger_moved = false;
						is_ipad = true;
						options['main_menu_hover_in'].apply($(this));
						
						return false;
					});
										
					$(this).bind("touchend", function(event) {											
						event.preventDefault();
						
						if (!finger_moved) { // prevent an accidental click
						
							$("body").find("#ipad_loading").stop().fadeIn(400);
							$("#top_banner").stop().animate({ 'opacity':0 }, 400);
													
							$('#' + options['wrap_id']).load($(this).attr('href'), {
								'ajax': '1'
							}, function(){
								init_page();
								clearTimeout(loading_timeout);
								loading_timeout = setTimeout(function() { $("body").find("#ipad_loading").stop().fadeOut(200) }, 300);
							});
						} else
							options['main_menu_hover_out'].apply($(this));
						
						return false;
					});
					
					$(this).hover(function() {}, function() {});
					
					if (!$.browser.msie) {
						$(this).get(0).addEventListener("click", function(event) {
							if(is_ipad)							
								event.preventDefault();
						}, false);
					}
				});
			}
			
			function init_screens() {	
				//if (screen_width != obj.width()) {
				//	alert(screen_width + '!=' + $("#" + options['mask_id']).width());
					screen_width = options['width'];
					screen_count = 0
					
			  	var x_offset = 0;
			  	$("." + options['screen_class']).each(function(){
						$(this).find("a").each(function(){							
							$(this).bind("touchstart", function() {
								finger_moved = false;
							});								
							$(this).bind("touchend", function() {
								if(!finger_moved) // prevent an accidental click
									change_screen($(this).attr("screen") - 1);
							});				
							$(this).click(function() {
								change_screen($(this).attr("screen") - 1);
							});
						});
						
						$("#" + options['mask_id']).find(".nav").append('<div id="slider_nav_' + screen_count + '" screen="' + screen_count + '"></div>');
						
						$("#" + options['mask_id']).find(".nav #slider_nav_" + screen_count).click(function() {
							change_screen($(this).attr("screen"));
						});
						
		  			$("#" + options['mask_id']).find(".nav").width((screen_count + 1) * (options['nav_button_size'] + options['nav_button_spacing']) + 'px');
						if($.browser.msie && $.browser.version=="6.0") 
							$("#" + options['mask_id']).find(".nav").width(($("#" + options['mask_id']).find(".nav").width() + options['nav_button_spacing']) + 'px');
			
							if (!$.browser.msie) {
							// setup events
							$(this).get(0).addEventListener("touchstart", touchStart, false);
							$(this).get(0).addEventListener("touchmove", touchMove, false);
							$(this).get(0).addEventListener("touchend", touchEnd, false);
							$(this).get(0).addEventListener("touchcancel", touchCancel, false);
						}
			
			  		$(this).css({
			  			top: '0px',
			  			left: x_offset + 'px',
			  			width: screen_width + 'px'
			  		});
			  		x_offset += parseInt(screen_width);
			  		screen_count++;
			  	});
					  	
			  	obj.width(x_offset);
					
			  	// reset screen
			  	show_screen(false);
		//	  }
				
				if (options['height'])
					height = options['height'];
				else		
					height = window.innerHeight;
					
				if (options['autosize']) {
					if ($("#" + options['mask_id']).height() != height) {
				  	$("#" + options['mask_id']).height(height);
				  	$("#" + options['mask_id']).width(width);
				  }
				}
						
				if(options['banner_id'] && obj.height() != (height - $("#" + options['banner_id']).height()))
						obj.height(height - $("#" + options['banner_id']).height());
				
				// adjust to orientation change
			//	setTimeout(init_screens, 400);
			
				$("#" + options['mask_id']).find(".nav").find("div").css({
					'position': 'relative',
					'float': 'left',
					'width': options['nav_button_size'] + 'px',
					'height': options['nav_button_size'] + 'px',
					'margin-left': options['nav_button_spacing'] + 'px',
					'background-image': 'url("' + options['nav_buttons_img'] + '")',
					'background-position': '0px 0px',
					'background-repeat': 'no-repeat',
					'cursor': 'pointer'
				});
				
				if(screen_count <= 1)
					$("#" + options['mask_id']).find(".nav_wrap").remove();
				
				show_screen(false);
			}
		
			function next_screen() {
				if(current_screen < (screen_count - 1))
					current_screen++;
					
				show_screen(true);
			}
			
			function last_screen() {
				if(current_screen >= 1)
					current_screen--;
					
				show_screen(true);
			}
			
			function change_screen(screen_id) {
				current_screen = screen_id;
					
				show_screen(true);
			}
			
			function scroll_down() {
				//obj.css({top: '-200px'});
			}
			
			function scroll_up() {
				
			}
			
			function show_screen(animate) {
				if (animate) {
			  	obj.stop(true, false).animate({
			  		left: '-' + (screen_width * current_screen) + 'px'
			  	}, 300, options['easing']);
			  } else {
			  	obj.stop(true, false).css({
			  		left: '-' + (screen_width * current_screen) + 'px'
			  	});
			  }
				
				$("#" + options['mask_id']).find(".nav div").css({
		  		'background-position': '0px 0px'
		  	});
		  	
		  	$("#" + options['mask_id']).find(".nav #slider_nav_" + current_screen).css({
		  		'background-position': '-' + options['nav_button_size'] + 'px' + ' 0px'
		  	});
			}
			
			function touchStart(event) {			
				is_ipad = true;
						
				fingerCount = event.touches.length;
				if ( fingerCount == 1 ) {
					startX = event.touches[0].pageX;
					startY = event.touches[0].pageY;
				} else {
					touchCancel(event);
				}
			}
			
			function touchMove(event) {
				finger_moved = true;
				
				event.preventDefault();
				if ( event.touches.length == 1 ) {
					curX = event.touches[0].pageX;
					curY = event.touches[0].pageY;
					
					if (options['scrolling']) {
					/*	scrollY += (curY - startY);
						
						if(scrollY < 0)
							scrollY = 0;
						else if(scrollY > $("#" + options['mask_id']).outerHeight())
							scrollY = $("#" + options['mask_id']).outerHeight();				*/		
							
						$("#" + options['mask_id']).scrollTop(scrollY);
					}
					var tmp_left = ((curX - startX) - (screen_width * current_screen));
					if(!options['elastic']) {
						if(tmp_left > 0)
							tmp_left = 0;
						if(tmp_left < (0 - (obj.width() - screen_width)))
							tmp_left = (0 - (obj.width() - screen_width));
					}
			  	obj.stop(true, true).css({
			  		left: tmp_left + 'px'
			  	});		
				} else {
					touchCancel(event);
				}
				
				return false;
			}
			
			function touchEnd(event) {	
				if ( fingerCount == 1 && curX != 0 ) {
					swipeLength = Math.round(Math.sqrt(Math.pow(curX - startX,2) + Math.pow(curY - startY,2)));
					if ( swipeLength >= options['swipe_length'] ) {
						calculateAngle();
						determineSwipeDirection();
						processingRoutine();
						touchCancel(event);
					} else {
						touchCancel(event);
					}	
				} else {
					touchCancel(event);
				}
			}
			
			function touchCancel(event) {
				fingerCount = 0;
				startX = 0;
				startY = 0;
				curX = 0;
				curY = 0;
				deltaX = 0;
				deltaY = 0;
				horzDiff = 0;
				vertDiff = 0;
				swipeLength = 0;
				swipeAngle = null;
				swipeDirection = null;
			
				show_screen(true); // reset screen
			}
			
			function calculateAngle() {
				var X = startX-curX;
				var Y = curY-startY;
				var Z = Math.round(Math.sqrt(Math.pow(X,2)+Math.pow(Y,2)));
				var r = Math.atan2(Y,X);
				swipeAngle = Math.round(r*180/Math.PI);
				if ( swipeAngle < 0 ) { swipeAngle =  360 - Math.abs(swipeAngle); }
			}
			
			function determineSwipeDirection() {
				if ( (swipeAngle <= 45) && (swipeAngle >= 0) ) {
					swipeDirection = 'left';
				} else if ( (swipeAngle <= 360) && (swipeAngle >= 315) ) {
					swipeDirection = 'left';
				} else if ( (swipeAngle >= 135) && (swipeAngle <= 225) ) {
					swipeDirection = 'right';
				} else if ( (swipeAngle > 45) && (swipeAngle < 135) ) {
					swipeDirection = 'down';
				} else {
					swipeDirection = 'up';
				}
			}
			
			function processingRoutine() {
				switch(swipeDirection) {
					case 'left':
							next_screen();
						break;
					case 'right':
							last_screen();
						break;
					case 'up':
							scroll_down();
						break;
					case 'down':
							scroll_up()
						break;
					default:			
						show_screen(true); // reset screen
						break;
				}
			}
		}
	});
})(jQuery);	
