/*
 * jQuery Impromptu
 * By: Trent Richardson [http://trentrichardson.com]
 * Version 3.1
 * Last Modified: 3/30/2010
 * 
 * Copyright 2010 Trent Richardson
 * Dual licensed under the MIT and GPL licenses.
 * http://trentrichardson.com/Impromptu/GPL-LICENSE.txt
 * http://trentrichardson.com/Impromptu/MIT-LICENSE.txt
 * 
 */
 
(function($) {
	$.prompt = function(message, options) {
		options = $.extend({},$.prompt.defaults,options);
		$.prompt.currentPrefix = options.prefix;

		var ie6		= ($.browser.msie && $.browser.version < 7);
		var $body	= $(document.body);
		var $window	= $(window);
		
		options.classes = $.trim(options.classes);
		if(options.classes != '')
			options.classes = ' '+ options.classes;
			
		//build the box and fade
		var msgbox = '<div class="'+ options.prefix +'box'+ options.classes +'" id="'+ options.prefix +'box">';
		if(options.useiframe && (($('object, applet').length > 0) || ie6)) {
			msgbox += '<iframe src="javascript:false;" style="display:block;position:absolute;z-index:-1;" class="'+ options.prefix +'fade" id="'+ options.prefix +'fade"></iframe>';
		} else {
			if(ie6) {
				$('select').css('visibility','hidden');
			}
			msgbox +='<div class="'+ options.prefix +'fade" id="'+ options.prefix +'fade"></div>';
		}
		msgbox += '<div class="'+ options.prefix +'" id="'+ options.prefix +'"><div class="'+ options.prefix +'container"><div class="';
		msgbox += options.prefix +'close">X</div><div id="'+ options.prefix +'states"></div>';
		msgbox += '</div></div></div>';

		var $jqib	= $(msgbox).appendTo($body);
		var $jqi	= $jqib.children('#'+ options.prefix);
		var $jqif	= $jqib.children('#'+ options.prefix +'fade');

		//if a string was passed, convert to a single state
		if(message.constructor == String){
			message = {
				state0: {
					html: message,
				 	buttons: options.buttons,
				 	focus: options.focus,
				 	submit: options.submit
			 	}
		 	};
		}

		//build the states
		var states = "";

		$.each(message,function(statename,stateobj){
			stateobj = $.extend({},$.prompt.defaults.state,stateobj);
			message[statename] = stateobj;

			states += '<div id="'+ options.prefix +'_state_'+ statename +'" class="'+ options.prefix + '_state" style="display:none;"><div class="'+ options.prefix +'message">' + stateobj.html +'</div><div class="'+ options.prefix +'buttons">';
			$.each(stateobj.buttons, function(k, v){
				if(typeof v == 'object')
					states += '<button name="' + options.prefix + '_' + statename + '_button' + v.title.replace(/[^a-z0-9]+/gi,'') + '" id="' + options.prefix + '_' + statename + '_button' + v.title.replace(/[^a-z0-9]+/gi,'') + '" value="' + v.value + '">' + v.title + '</button>';
				else states += '<button name="' + options.prefix + '_' + statename + '_button' + k + '" id="' + options.prefix +	'_' + statename + '_button' + k + '" value="' + v + '">' + k + '</button>';
			});
			states += '</div></div>';
		});

		//insert the states...
		$jqi.find('#'+ options.prefix +'states').html(states).children('.'+ options.prefix +'_state:first').css('display','block');
		$jqi.find('.'+ options.prefix +'buttons:empty').css('display','none');
		
		//Events
		$.each(message,function(statename,stateobj){
			var $state = $jqi.find('#'+ options.prefix +'_state_'+ statename);

			$state.children('.'+ options.prefix +'buttons').children('button').click(function(){
				var msg = $state.children('.'+ options.prefix +'message');
				var clicked = stateobj.buttons[$(this).text()];
				if(clicked == undefined){
					for(var i in stateobj.buttons)
						if(stateobj.buttons[i].title == $(this).text())
							clicked = stateobj.buttons[i].value;
				}
				
				if(typeof clicked == 'object')
					clicked = clicked.value;
				var forminputs = {};

				//collect all form element values from all states
				$.each($jqi.find('#'+ options.prefix +'states :input').serializeArray(),function(i,obj){
					if (forminputs[obj.name] === undefined) {
						forminputs[obj.name] = obj.value;
					} else if (typeof forminputs[obj.name] == Array || typeof forminputs[obj.name] == 'object') {
						forminputs[obj.name].push(obj.value);
					} else {
						forminputs[obj.name] = [forminputs[obj.name],obj.value];	
					} 
				});

				var close = stateobj.submit(clicked,msg,forminputs);
				if(close === undefined || close) {
					removePrompt(true,clicked,msg,forminputs);
				}
			});
			$state.find('.'+ options.prefix +'buttons button:eq('+ stateobj.focus +')').addClass(options.prefix +'defaultbutton');

		});

		var ie6scroll = function(){
			$jqib.css({top: $window.scrollTop()});
		};

		var fadeClicked = function(){
			if(options.persistent){
				var i = 0;
				$jqib.addClass(options.prefix +'warning');
				var intervalid = setInterval(function(){
					$jqib.toggleClass(options.prefix +'warning');
					if(i++ > 1){
						clearInterval(intervalid);
						$jqib.removeClass(options.prefix +'warning');
					}
				}, 100);
			}
			else {
				removePrompt();
			}
		};
		
		var keyPressEventHandler = function(e){
			var key = (window.event) ? event.keyCode : e.keyCode; // MSIE or Firefox?
			
			//escape key closes
			if(key==27) {
				fadeClicked();	
			}
			
			//constrain tabs
			if (key == 9){
				var $inputels = $(':input:enabled:visible',$jqib);
				var fwd = !e.shiftKey && e.target == $inputels[$inputels.length-1];
				var back = e.shiftKey && e.target == $inputels[0];
				if (fwd || back) {
				setTimeout(function(){ 
					if (!$inputels)
						return;
					var el = $inputels[back===true ? $inputels.length-1 : 0];

					if (el)
						el.focus();						
				},10);
				return false;
				}
			}
		};
		
		var positionPrompt = function(){
			$jqib.css({
				position: (ie6) ? "absolute" : "fixed",
				height: $window.height(),
				width: "100%",
				top: (ie6)? $window.scrollTop() : 0,
				left: 0,
				right: 0,
				bottom: 0
			});
			$jqif.css({
				position: "absolute",
				height: $window.height(),
				width: "100%",
				top: 0,
				left: 0,
				right: 0,
				bottom: 0
			});
			$jqi.css({
				position: "absolute",
				top: options.top,
				left: "50%",
				marginLeft: (($jqi.outerWidth()/2)*-1)
			});
		};

		var stylePrompt = function(){
			$jqif.css({
				zIndex: options.zIndex,
				display: "none",
				opacity: options.opacity
			});
			$jqi.css({
				zIndex: options.zIndex+1,
				display: "none"
			});
			$jqib.css({
				zIndex: options.zIndex
			});
		};

		var removePrompt = function(callCallback, clicked, msg, formvals){
			$jqi.remove();
			//ie6, remove the scroll event
			if(ie6) {
				$body.unbind('scroll',ie6scroll);
			}
			$window.unbind('resize',positionPrompt);
			$jqif.fadeOut(options.overlayspeed,function(){
				$jqif.unbind('click',fadeClicked);
				$jqif.remove();
				if(callCallback) {
					options.callback(clicked,msg,formvals);
				}
				$jqib.unbind('keypress',keyPressEventHandler);
				$jqib.remove();
				if(ie6 && !options.useiframe) {
					$('select').css('visibility','visible');
				}
			});
		};

		positionPrompt();
		stylePrompt();
		
		//ie6, add a scroll event to fix position:fixed
		if(ie6) {
			$window.scroll(ie6scroll);
		}
		$jqif.click(fadeClicked);
		$window.resize(positionPrompt);
		$jqib.bind("keydown keypress",keyPressEventHandler);
		$jqi.find('.'+ options.prefix +'close').click(removePrompt);

		//Show it
		$jqif.fadeIn(options.overlayspeed);
		$jqi[options.show](options.promptspeed,options.loaded);
		$jqi.find('#'+ options.prefix +'states .'+ options.prefix +'_state:first .'+ options.prefix +'defaultbutton').focus();
		
		if(options.timeout > 0)
			setTimeout($.prompt.close,options.timeout);

		return $jqib;
	};
	
	$.prompt.defaults = {
		prefix:'jqi',
		classes: '',
		buttons: {
			Ok: true
		},
	 	loaded: function(){

	 	},
	  	submit: function(){
	  		return true;
		},
	 	callback: function(){

	 	},
		opacity: 0.6,
	 	zIndex: 999,
	  	overlayspeed: 'slow',
	   	promptspeed: 'fast',
   		show: 'fadeIn',
	   	focus: 0,
	   	useiframe: false,
	 	top: "15%",
	  	persistent: true,
	  	timeout: 0,
	  	state: {
			html: '',
		 	buttons: {
		 		Ok: true
		 	},
		  	focus: 0,
		   	submit: function(){
		   		return true;
		   }
	  	}
	};
	
	$.prompt.currentPrefix = $.prompt.defaults.prefix;

	$.prompt.setDefaults = function(o) {
		$.prompt.defaults = $.extend({}, $.prompt.defaults, o);
	};
	
	$.prompt.setStateDefaults = function(o) {
		$.prompt.defaults.state = $.extend({}, $.prompt.defaults.state, o);
	};
	
	$.prompt.getStateContent = function(state) {
		return $('#'+ $.prompt.currentPrefix +'_state_'+ state);
	};
	
	$.prompt.getCurrentState = function() {
		return $('.'+ $.prompt.currentPrefix +'_state:visible');
	};
	
	$.prompt.getCurrentStateName = function() {
		var stateid = $.prompt.getCurrentState().attr('id');
		
		return stateid.replace($.prompt.currentPrefix +'_state_','');
	};
	
	$.prompt.goToState = function(state, callback) {
		$('.'+ $.prompt.currentPrefix +'_state').slideUp('slow');
		$('#'+ $.prompt.currentPrefix +'_state_'+ state).slideDown('slow',function(){
			$(this).find('.'+ $.prompt.currentPrefix +'defaultbutton').focus();
			if (typeof callback == 'function')
				callback();
		});
	};
	
	$.prompt.nextState = function(callback) {
		var $next = $('.'+ $.prompt.currentPrefix +'_state:visible').next();

		$('.'+ $.prompt.currentPrefix +'_state').slideUp('slow');
		
		$next.slideDown('slow',function(){
			$next.find('.'+ $.prompt.currentPrefix +'defaultbutton').focus();
			if (typeof callback == 'function')
				callback();
		});
	};
	
	$.prompt.prevState = function(callback) {
		var $next = $('.'+ $.prompt.currentPrefix +'_state:visible').prev();

		$('.'+ $.prompt.currentPrefix +'_state').slideUp('slow');
		
		$next.slideDown('slow',function(){
			$next.find('.'+ $.prompt.currentPrefix +'defaultbutton').focus();
			if (typeof callback == 'function')
				callback();
		});
	};
	
	$.prompt.close = function() {
		$('#'+ $.prompt.currentPrefix +'box').fadeOut('fast',function(){
        		$(this).remove();
		});
	};
	
	$.fn.prompt = function(options){
		if(options == undefined) 
			options = {};
		if(options.withDataAndEvents == undefined)
			options.withDataAndEvents = false;
			
		$.prompt($(this).clone(options.withDataAndEvents).html(),options);
	};

})(jQuery);


/*
 * jQuery Impromptu Extension
 * By: John Dobiatowski [http://dobiatowski.blogspot.com]
 * Version 0.9.4 for jQuery Impromptu 3.1+
 * Last Modified: 8/23/2011
 *
 * Copyright 2010 John Dobiatowski
 * Attribution-ShareAlike 3.0 Unported
 * http://creativecommons.org/licenses/by-sa/3.0/
 *
 * Improvements:
 *  v0.9.4
 *	 [bugfix] IE9 on Vista, problem with capture submit event removed.
 *
 *	v0.9.3
 *   [feature] submiting forms on enter event inside prompt
 *	        it support several forms in prompt, they are detected by form name
 *			  for example: login form and register form opened in one prompt
 *
 *   [fix] performance problem in zoom mode fixed
 *		     when zoom in IE8 is set, all animations of prompt slow down dramaticly and event stuck
 *		     (tested on 2,8GHz CPU, 2GB RAM, WinXP)
 *		     patch detect zoom and turn off animations
 *
 *   [fix] prompt reopen problem - if there is already prompt with the same ID, it close it and open new one
 *         it prevents situations when you could open serveral the same prompts, one overlapping other
 *
 * Usage:
 *
 *   This is extension of jQuery Impromptu, so you need both files:
 *	    - jQuery Impromptu Version 3.1+
 *	      download: http://trentrichardson.com/Impromptu/index.php
 *     - jQuery Impromptu Extension Version 0.9.3 for jQuery Impromptu 3.1+
 *       download: http://dobiatowski.blogspot.com/
 *
 */
(function($) {

	$.prompt.submit = function(clicked) {
		var $state = $.prompt.getCurrentState();
		var msg = $state.children('.'+ $.prompt.tempOptions.prefix +'message');
		//var clicked = true;
		var forminputs = {};
		var $jqi = $('#'+$.prompt.currentPrefix);

		//collect all form element values from all states
		$.each($jqi.find('#'+ $.prompt.tempOptions.prefix +'states :input').serializeArray(),function(i,obj){
			if (forminputs[obj.name] === undefined) {
				forminputs[obj.name] = obj.value;
			} else if (typeof forminputs[obj.name] == Array || typeof forminputs[obj.name] == 'object') {
				forminputs[obj.name].push(obj.value);
			} else {
				forminputs[obj.name] = [forminputs[obj.name],obj.value];
			}
		});

		var close = $.prompt.tempOptions.submit(clicked,msg,forminputs);
		if(close === undefined || close) {
			$.prompt.close();
		}

	};

	$.prompt.tempOptions;
	
	$.promptExt = function(message, options) {

		// if user uses IE8 in zoom mode turn off all animations - performance problems
		// there is no universal solution to detect zoom level in all browsers
		// the only one uses adobe flash hack - but this is unnecessary complication
		// http://stackoverflow.com/questions/1713771/how-to-detect-page-zoom-level-in-all-modern-browsers
		var zoom = window.screen.deviceXDPI;
		if (typeof(zoom) != "undefined" && zoom != 96) {
			options.overlayspeed = 0;
			options.promptspeed = 0;
			options.show = 'show';
		}

		$.prompt.tempOptions = $.extend({},$.prompt.defaults,options);

		// if there is prompt with the same ID close it and wait to remove old instance
		if ($('#'+ $.prompt.tempOptions.prefix).length != 0) {
			$.prompt.close();
			setTimeout(function() {
				$.promptExt(message, options);
			}, 250);
			return;
		}

		$.prompt(message, options);

		// submiting the prompt after enter event on form input inside prompt
		// enter key event is fired also on autocomplete list displayed for particular input
		// this is the way to prevent submiting the form in that case
		// also there is a bug in firefox discussed here:
		// http://stackoverflow.com/questions/2303955/i-have-a-problem-with-keydown-event-and-autocomplete-in-firebox-on-mac
		// which forced me to use setTimeout hack
		var oldInputValue;
		var keyPressEventHandler = function(event) {
			//enter key
			if(event.keyCode==13) {
				 setTimeout(function() {enterEventHandler(event);},0);
				 return false;
			}
			else
				$.promptExt.oldInputValue = event.currentTarget.value;
		}
		var enterEventHandler = function(event) {
			if($.promptExt.oldInputValue == event.currentTarget.value)
				//function sends a name of parent form of input which was hit by enter key
				//it helps in situation when in prompt you have more then one form - this will determine which one was "submited"
				//example: login form and register form opened in one prompt
				$.prompt.submit(event.currentTarget.form.name);
			else
				$.promptExt.oldInputValue = event.currentTarget.value;
		};

		// prevent all forms inside prompt against page reload on submit action
		$('#'+ $.prompt.tempOptions.prefix +'states form').submit(function () { return false; });

		// bind key event to every input in prompt
		$('#'+ $.prompt.tempOptions.prefix +'states .'+ $.prompt.tempOptions.prefix +'message :input').bind("keyup focus",keyPressEventHandler);

		// todo: set focus for first input inside prompt
		// problematic
		// $('#'+ $.prompt.tempOptions.prefix +'states input[type=text]')[0].focus();

	}
})(jQuery);

