
/** DWCookie *********************/
function DWCookie( key ) {
	this.key = key;
}
Object.extend( DWCookie.prototype, {
	read: function() {
		var map = DWCookie.getMap();
		if( this.key in map ) {
			return unescape(map[this.key]);
		}
		return null;
	},
	
	update: function( value, options ) {
		var data = [];
		data.push( [this.key, escape(value)].join('=') );
		if( ('object'==typeof options) && ('days' in options) ) {
			var date = new Date();
			date.setTime(date.getTime() + (options['days'] * 24 * 60 * 60 * 1000));
			data.push( ['expires', date.toGMTString()].join('=') );
		}
		data.push( ['path', '/'].join('=') );
		document.cookie = data.join('; ');
	}
} );

Object.extend( DWCookie, {
	__map: null,
	getMap: function() {
		if( null==DWCookie.__map ) {
			DWCookie.__map = {};
			document.cookie.split(/\s*;\s*/).each( function( cookie ) {
				var keyValue = cookie.split( '=', 2 );
				if( keyValue.length==2 ) {
					DWCookie.__map[ keyValue[0] ] = keyValue[1];
				}
			} );
		}
		return DWCookie.__map;
	},
	isEnabled: function() {
		var value = (new DWCookie('sid')).read();
		return( null!=value && value.length > 0 );
	}
} );

/** user agent detection **/
function addUAClasses() {
	if(navigator.userAgent != null) {
		if (navigator.userAgent.indexOf('iPad') != -1 || navigator.userAgent.indexOf('Android') != -1) {
			var additionalBodyClasses = "devicegroup-tablet"
			navigator.userAgent.indexOf('iPad') != -1 ? additionalBodyClasses += " devicetype-ipad" : additionalBodyClasses += " devicetype-android";
			jQuery('body').addClass(additionalBodyClasses);
		}
	}
}

/** JavaScript SliderBoxes ******/
function InitSliderBoxes() {
	jQuery(".showSliderBox").each(function() {
		var overElement = jQuery(this).children('.showSliderHover').first();
		if(null != overElement) {
			var heightParent = jQuery(this).height();
			var heightOver = jQuery(overElement).height();
			if ( heightOver + parseInt(jQuery(overElement).css('bottom')) > 0 ) {
				minBottom = parseInt(jQuery(overElement).css('bottom'));				
			} else {
				var minBottom = 0 - heightOver;
			}
			var maxBottom = heightOver > heightParent ? 0 - (heightOver - heightParent) : 0;
			jQuery(this).hover(function(event){jQuery(overElement).animate({'bottom' : maxBottom}, 400);},function(event){jQuery(overElement).animate({'bottom' : minBottom}, 300);});
		}
	});
}


/** Overlay *********************/
// TODO...

/** Category Overlay (API) *********************/
function CategoryOverlay() {
	$$('#category_overlay .close').each( function(item) {
		item.observe( 'click', CategoryOverlay.close );
	} );
}
Object.extend( CategoryOverlay, {
	close: function() {
		$('category_overlay').hide();
		var overlayID = $('category_overlay').getAttribute('data-overlay');
		CategoryOverlay.updateCookie( overlayID );
		CategoryOverlay.updateSession( overlayID );
	},
	
	updateCookie: function( overlayID ) {
		var cookie = new DWCookie( 'overlays' );
		var value = cookie.read();
		if( typeof value=='string' && value.length!=0 ) {
			value = value.split('|'); 
		}
		else {
			value = [];
		}
		value.push( overlayID );
		cookie.update( value.join('|'), { days: 31 } );
	},
	
	updateSession: function( overlayID ) {
		//TODO: interact with the server
	}
	
} );

/** Observe dom loading *********/
if( 'observe' in document ) {
	document.observe('dom:loaded', function() {
		addUAClasses();
		new CategoryOverlay();
		InitSliderBoxes();
	});
}

/* changes a Parameter in a URL String */ 
function changeParameterInURL(search, param, value)
{
    var regexp = new RegExp("(\\?|\\&)" + param + "\\=([^\\&]*)(\\&|$)");
    if (regexp.test(search)) {
        return (search.replace(regexp, function(a, b, c, d)
        {
                return (b + param + "=" + value + d);
        }));}
    else {
    	return search + param + "=" + value;
    }
    	
};

/* native read a cookie */
function readCookie(name) {
	var nameEQ = name + "=";
	var ca = document.cookie.split(';');
	for(var i=0;i < ca.length;i++) {
		var c = ca[i];
		while (c.charAt(0)==' ') c = c.substring(1,c.length);
		if (c.indexOf(nameEQ) == 0) return unescape(c.substring(nameEQ.length,c.length));
	}
	return null;
}

/* native write a cookie */
function createCookie(name,value,days) {
	if (days) {
		var date = new Date();
		date.setTime(date.getTime()+(days*24*60*60*1000));
		var expires = "; expires="+date.toGMTString();
	}
	else var expires = "";
	document.cookie = name+"="+value+expires+"; path=/";
}

var app = (function(jQuery) {
	
	if (!jQuery) {
		alert('app initialization failure');
		return null;
	}
	
	return {
		
		URLs			: {}, // holds dw specific urls, check htmlhead.isml for some examples
		resources		: {},  // resource strings used in js
		constants		: {}, // platform constants, initialized in htmlhead.isml
		containerId		: "content",
		clearDivHtml	: "<div class=\"clear\"><!-- W3C Clearing --></div>",	
		
		// default dialog box settings
		dialogSettings: {
				bgiframe: true, // this is required mainly for IE6 where drop downs bleed into dialogs!!! it depends on 
				autoOpen: false,
				buttons: {},
				modal: true,
				overlay: {
		    		opacity: 0.5,
		     		background: "black"
				},
		    	height: 530,
		    	width: 800,
		    	title: '',
		    	// show: "slow", This is causing dialog to break in jquery 1.3.2 rel, show: "slide" works but not desired
		    	hide: "normal",
		    	resizable: false
		},
		
		// sub namespace app.ajax.* contains application specific ajax components
		ajax: {
			Success: "success",
			currentRequests: {}, // request cache

			// ajax request to get json response
			// @param - reqName - String - name of the request
			// @param - async - boolean - asynchronous or not
			// @param - url - String - uri for the request
			// @param - data - name/value pair data request
			// @param - callback - function - callback function to be called
			getJson: function(options) {
				var thisAjax = this;

				// do not bother if the request is already in progress
				// and let go null reqName
				if (!options.reqName || !this.currentRequests[options.reqName]) {
					this.currentRequests[options.reqName] = true;
					if(options.async == "undefined") options.async = true;
					// make the server call
					jQuery.ajax({
						contentType: "application/json; charset=utf-8",
						dataType: "json",
						url		: options.url,
						cache	: true,
						async	: options.async,
						data	: options.data,

						success: function(response, textStatus) {
							thisAjax.currentRequests[options.reqName] = false;

							if (!response.Success) {
								// handle failure
							}

							options.callback(response, textStatus);
						},

						error: function(request, textStatus, error) {
							if (textStatus === "parsererror") {
								alert(app.resources["BAD_RESPONSE"]);
							}
							
							options.callback({Success: false, data:{}});
						}
					});
				}
			},

			// ajax request to load html response in a given container
			// @param - reqName - String - name of the request
			// @param - url - String - uri for the request
			// @param - data - name/value pair data request
			// @param - callback - function - callback function to be called
			// @param - selector - string - id of the container div/span (#mycontainer) - it must start with '#'
			load: function(options) {

				var thisAjax = this;

				// do not bother if the request is already in progress
				// and let go null reqname
				if (!options.reqName || !this.currentRequests[options.reqName]) {
					this.currentRequests[options.reqName] = true;
					// make the server call
					jQuery.ajax({
						dataType: "html",
						url		: options.url,
						cache	: true,
						data	: options.data,

						success: function(response, textStatus) {
							thisAjax.currentRequests[options.reqName] = false;
							
							if (options.selector) {
								jQuery(options.selector).html(response);
							}

							(options.callback != undefined ? options.callback(response, textStatus): null)
						},

						error: function(request, textStatus, error) {
							if (textStatus === "parsererror") {
								alert(app.resources["BAD_RESPONSE"]);
							}

							options.callback(null, textStatus);
						}
					});
				}
			}
		},		
	
		// sub namespace app.dialog.* provides convenient functions to handle dialogs
		// note, that this code relies on single dialog modals (multi dialog, e.g. modal in modal is not supported)
		dialog : {
			
			dialogHeight : 425,
			dialogWidth	 : 460,	
			
			// opens a dialog using the given url
			open : function(url, title, closetext) {
				// call global wait Dialog
				jQuery("#statusWnd").show();
				jQuery("#statusWndPleaseWait").show();
			
				// create the dialog container if not present already
				if(jQuery("#dialogcontainer").length == 0) {
					jQuery(document.body).append("<div id=\"dialogcontainer\"></div>");
					jQuery("#dialogcontainer").dialog({
						bgiframe: true,
						autoOpen: false,
						modal: true,
						overlay: {
				    		opacity: 0.5,
				     		background: "black"
						},
						height: app.dialog.dialogHeight, //425,
				    	width: app.dialog.dialogWidth, //460,
				    	resizable: false
					});
				}
	
				// set a default title
				title = title || "Dialog";
	
				// finally load the dialog, set the dialog title
				app.ajax.load({
					selector: "#dialogcontainer",
					url: url,
					callback: function() {
						app.dialog.checkOpen();
						app.dialog.setTitle(title);
						if(typeof(closetext) != "undefined") {
							app.dialog.setCloseText(closetext);
						}
						jQuery("#statusWnd").hide();
						jQuery("#statusWndPleaseWait").hide();
					}
				});
			},
	
			// initializes the dialog with common dialog actions, like closing upon canceling
			// use this function in the dialog rendering template to re-bind common actions
			// upon dialog reload
			init : function() {
				jQuery(document).ready(function() {
					// binds the action to all buttons defining an action through the "name" attribute
					jQuery("#dialogcontainer button").each(function() {
						jQuery(this).click(function() {
							var action = jQuery(this).attr("name");
							if(action) {
								app.dialog.submit(action);
							}
							return false;
						});
					});
	
					// cancel button binding
					jQuery("#dialogCancelBtn").click(function() {
						app.dialog.close();
						return false;
					});
				});
			},
	
			// sets the title of the dialog
			setTitle : function(title) {
				jQuery("#dialogcontainer").dialog("option", "title", title);
			},
			// sets the closetext of the dialog
			setCloseText : function(closetext) {
				jQuery("#dialogcontainer").dialog("option", "closeText", closetext);
			},			
	
			// checks, if the dialog is in the state "open" and sets the state if not presently set
			// this function is implicitly called by app.dialog.open(url, title) in order to initialize
			// the dialog properly; use this function to recover the "open" state of a dialog
			checkOpen : function() {
				if(!jQuery("#dialogcontainer").dialog("isOpen"))
				{
					jQuery("#dialogcontainer").dialog({
						bgiframe: true,
						autoOpen: false,
						modal: true,
						overlay: {
				    		opacity: 0.5,
				     		background: "black"
						},
						height: app.dialog.dialogHeight, //425,
				    	width: app.dialog.dialogWidth, //460,
				    	resizable: false
					});
					jQuery("#dialogcontainer").dialog("open");
				}
			},
	
			// closes the dialog and triggers the "close" event for the dialog
			close : function() {
				jQuery("#dialogcontainer").dialog("close");
				jQuery(document.body).trigger("dialogClosed");
			},
	
			// attaches the given callback function upon dialog "close" event
			onClose : function(callback) {
				if(callback != undefined) {
					jQuery(document.body).bind("dialogClosed", callback);
				}
			},
	
			// triggers the "apply" event for the dialog
			triggerApply : function() {
				jQuery(document.body).trigger("dialogApplied");
			},
	
			// attaches the given callback function upon dialog "apply" event
			onApply : function(callback) {
				if(callback != undefined) {
					jQuery(document.body).bind("dialogApplied", callback);
				}
			},
	
			// triggers the "delete" event for the dialog
			triggerDelete : function() {
				jQuery(document.body).trigger("dialogDeleted");
			},
	
			// attaches the given callback function upon dialog "delete" event
			onDelete : function(callback) {
				if(callback != undefined) {
					jQuery(document.body).bind("dialogDeleted", callback);
				}
			},
	
			// submits the dialog form with the given action
			submit : function(action) {
				// set the action
				jQuery("#dialogcontainer form").append("<input name=\"" + action + "\" type=\"hidden\" />");
	
				// serialize the form and get the post url
				var post = jQuery("#dialogcontainer form").serialize();		
				var url = jQuery("#dialogcontainer form").attr("action");
				
				jQuery("#statusWnd").show();
				jQuery("#statusWndPleaseWait").show();
	
				// post the data and replace current content with response content
		  		jQuery.ajax({
				   type: "POST",
				   url: url,
				   data: post,
				   dataType: "html",
				   success: function(data){
		  				jQuery("#dialogcontainer").empty().html(data);
		  				jQuery("#statusWnd").hide();
						jQuery("#statusWndPleaseWait").hide();
				   },
				   failure: function(data) {
					   jQuery("#statusWnd").hide();
					   jQuery("#statusWndPleaseWait").hide();
					   alert(app.resources["SERVER_ERROR"]);
				   }
				});
			},
			
			//
			openResized : function(url, title, width, height, closetext) {
				app.dialog.dialogHeight = height;
				app.dialog.dialogWidth = width;
				app.dialog.open(url, title, closetext);
			}
		}
	}
}) (jQuery);
