/**
 * Javascript nova core
 *
 * @package nova
 * @subpackage javascript
 * @author Liquid Edge Solutions
 * @copyright Copyright Liquid Edge Solutions. All rights reserved.
 *
 * @todo remove $$getvalue function
 * @todo rework namespace layout to match api and com
 *///--------------------------------------------------------------------------------

// constants

//--------------------------------------------------------------------------------
C_UPDATE = 0;
C_FUNCTION = 1;
//--------------------------------------------------------------------------------

// class

//--------------------------------------------------------------------------------
var core = {
	version: '2.1',
	mootoolsVersion: '1.2.1',
	//--------------------------------------------------------------------------------
	ajax: {
		//--------------------------------------------------------------------------------
		request: function(url, options) {
			// init options
		  	options = $extend({
		  		callback	: false, 			// what to do after request: C_UPDATE, C_FUNCTION
		  		el			: $('panel_body'), 	// element used for overlay and/or update
		  		confirmText	: false, 			// text for display in confirm dialog
		  		func		: false, 			// function to run for use with C_FUNCTION callback
		  		form		: false, 			// form name OR array of form names to send as data
		  		data		: false,			// additional post data (key - value pairs)
		  		noOverlay	: false				// should this request create an overlay

			}, $pick(options, {}));

			// confirm dialog
			if (options.confirmText && !confirm(options.confirmText)) return;

			// overlay
			//if (!options.noOverlay)	options.overlayId = core.overlay.show(options.el, options.el.id + '_overlay');
			if (!options.noOverlay)	options.overlayId = core.overlay.show(options.el, 'ajax_overlay');

			// init request options
			var requestOptions = {
				url			: url,
				method		: 'post',
				onComplete	: function() { core.overlay.hide(this.options._core.overlayId); },
				onCancel	: function() { core.overlay.hide(this.options._core.overlayId); },

				_core		: options
			};

			// post data
			var dataArr = new Array();

			// forms
			if (options.form) dataArr.push(core.form.toUrl(options.form));

			// additional post data
			if (options.data) dataArr.push(options.data);

			if (dataArr.length > 0) requestOptions = $extend(requestOptions, { data: dataArr.join('&') });

			// init callback based request options
			switch (options.callback) {
				case C_UPDATE : // populate response into given element
					requestOptions = $extend(requestOptions, {
						evalScripts: true,
						update: $(options.el),
						onComplete: $empty,
						onSuccess: function() { core.overlay.hide(this.options._core.overlayId); }
					});
					break;

				case C_FUNCTION	: // call user function onSuccess
					requestOptions = $extend(requestOptions, {
						onSuccess: function(responseText, responseXML) {
							// check response for message signature
							if (responseText.test('^##MESSAGE##')) {
								// extract and view messages
								var messageArr = eval(responseText.replace('##MESSAGE##', ''));
								core.message.show('Notice', messageArr);
							}

							// call user function
							switch ($type(this.options._core.func)) {
								case 'string' : eval(this.options._core.func + '(responseText, this.options._core);'); break;
								case 'function' : this.options._core.func.run([responseText, this.options._core]); break;
							}
						}
					});
					break;
			}

			// init and send request object
			if (options.callback == C_UPDATE) new Request.HTML(requestOptions).send();
			else new Request(requestOptions).send();
		},
		//--------------------------------------------------------------------------------
		requestFunction: function(url, func, options) {
	    	// init options
	    	options = $extend({
		    		callback: C_FUNCTION,
		    		func: func
	    		},
	    		$pick(options, {})
	    	);

	    	// call request
    		core.ajax.request(url, options)
		},
		//--------------------------------------------------------------------------------
		requestUpdate: function(url, el, options) {
	    	// init options
	    	options = $extend({
		    		callback: C_UPDATE,
		    		el: el
	    		},
	    		$pick(options, {})
	    	);

	    	// call request
    		core.ajax.request(url, options)
		}
	},
	//--------------------------------------------------------------------------------
	overlay: {
		//--------------------------------------------------------------------------------
		show: function(el, id) {
			// init args
			el = $($pick(el, 'panel_body'));
			id = $pick(id, 'ajax_overlay');

			// validate
			if (!$defined(el)) return false;

			// hide objects that display on top of overlay
			$(el).getElements('object').each(function(eli) { eli.style.visibility = 'hidden'; } );
			$(el).getElements('select').each(function(eli) { eli.style.visibility = 'hidden'; } );

			// destroy tooltip objects
			$$('.tooltip').each(function(eli) { eli.destroy(); } );

			// init data
			var size = el.getSize();
			var position = el.getPosition();

			// set minimum size
			if (size.x < 100) size.x = 100;
			if (size.y < 35) size.y = 35;

			// hide current overlay
			core.overlay.hide();

			// create overlay
			var elOverlay = new Element('div', {
				'id': id,
				'class': 'ajax-overlay',
				'html' : (el.id == 'panel_body' ? '' : '<div class="ajax-wrapper"><img src="./themes/shared/icon_loading.gif" /> Loading...</div>'),
				'styles': {
					'top': position.y + 'px',
					'left': position.x + 'px',
					'width': size.x + 'px',
					'height': size.y + 'px'
				}
			});
			elOverlay.inject('panel_body', 'before');
			elOverlay.store('core', { el: el });

			// end
			return id;
		},
		//--------------------------------------------------------------------------------
		hide: function(id) {
			// init args
			id = $pick(id, 'ajax_overlay');

			// init
			var elOverlay = $(id);
			if ($defined(elOverlay)) {
				// init core options
				var core = elOverlay.retrieve('core');

				// destroy current overlay
				elOverlay.destroy();

				// show objects that display on top of overlay
				$(core.el).getElements('object').each(function(eli) { eli.style.visibility = 'visible'; } );
				$(core.el).getElements('select').each(function(eli) { eli.style.visibility = 'visible'; } );
			}
		}
	},
	//--------------------------------------------------------------------------------
	form: {
		//--------------------------------------------------------------------------------
		toUrl: function(formArr) {
			//init args
			formArr = $splat(formArr);

			// init data
			var urlArr = new Array();

			// loop form array
			$each(formArr, function(form) {
				form = $(form);

				// get form elements
				var elementArr = form.getElements('input,select,textarea');

				// loop element array
				$each(elementArr, function(element) {
					// dont process if nosubmit flag set
					if (!$defined(element.get('nosubmit'))) {
						// check for id
						if ($defined(element.name)) {
							// build url based on element type
					  	  	switch (element.type) {
					  	  	  	case 'hidden' 			:
					  	  	  	case 'text' 			:
					  	  	  	case 'password' 		:
					  	  	  	case 'textarea'			:
					  	  	  	case 'select-one' 		:
					  	  	  		urlArr.push(element.name + '=' + encodeURIComponent(element.get('value')));
					  	  	  		break;

					  	  	  	case 'checkbox' 		:
					  	  	  	case 'radio' 			:
					  	  	  		if (element.checked) urlArr.push(element.name + '=' + element.value);
					  	  	  		break;

								case 'select-multiple' 	:
									var optionArr = element.getElements('option');
									$each(optionArr, function(option) {
										if (option.selected) urlArr.push(element.name + '[]=' + encodeURIComponent(option.value));
									});
									break;

					  	  	  	default : break; // unsupported element type
					  	  	}
						}
					}
				});
			});

			return urlArr.join('&');
		},
		//--------------------------------------------------------------------------------
		isComplexPassword: function(text, minLength, requireNumber, requireLetter) {
			var checkNumeric = false;
			var checkAlpha = false;
			var checkAlphanumeric = false;

			var validChars = '0123456789';

			// length check
			if (text.length < minLength) return false;
			else {
				for (var i = 0; i < text.length && !checkAlphanumeric; i++) {
					// numeric check
					if (requireNumber) {
						var nChar = text.charAt(i);
						if (validChars.indexOf(nChar) > -1) checkNumeric = true;
					}

					// alpha check
					if (requireLetter) {
						var aCharCode = text.charCodeAt(i);
						if ((aCharCode >= 65 && aCharCode <= 90) || (aCharCode >= 97 && aCharCode <= 122)) checkAlpha = true;
					}

					if (checkNumeric && checkAlpha) checkAlphanumeric = true;
				}

				if (checkAlphanumeric) return true;
				else return false;
			}
		},
		//--------------------------------------------------------------------------------
		checkCount: function(name, checked) {
			// init args
			checked = $pick(checked, true);

			// init
			var count = 0;

			// count checkboxes
			var checkboxArr = document.getElements('input[name^=' + name + '[]');
			$each(checkboxArr, function(el) {
				if (el.checked == checked) count++;
			});

			// end
			return count;
		},
		//--------------------------------------------------------------------------------
		selectAll: function(selectEl) {
			$(selectEl).getElements('option').each(function(el) { el.selected = true; });
		},
		//--------------------------------------------------------------------------------
		selectNone: function(selectEl) {
			$(selectEl).getElements('option').each(function(el) { el.selected = false; });
		},
		//--------------------------------------------------------------------------------
		populateSelect: function(selectEl, url) {
			// init args
			selectEl = $(selectEl);
			selectEl.length = 0;

			// call request
			core.ajax.requestFunction(url, function(responseText) {
				eval('var option_arr = ' + responseText + ';');
				// populate select input
				$each(option_arr, function(item, index) {
					var option_item = document.createElement('option');
					option_item.text = item;
					option_item.value = index;
					selectEl.options.add(option_item);
				});
			}, { noOverlay: true});
		}
	},
	//--------------------------------------------------------------------------------
	bit: {
		//--------------------------------------------------------------------------------
		set: function(bit, bitValue, state) {
			state = $pick(state, true);
			bit = parseInt(bit);
			bitValue = parseInt(bitValue);

			if (state) return (bitValue | bit);
			else return (bitValue & ~bit);
		}
	},
	//--------------------------------------------------------------------------------
	message: {
		roar: false,
		//--------------------------------------------------------------------------------
		show: function(header, messageArr) {
			// init args
			messageArr = $splat(messageArr);

			// init roar object
			if (!this.roar) this.roar = new Roar({position: 'lowerRight', duration: 5000, offset: 5, margin: {x: 5, y: 5}});

			// init message
			var message = '';
			messageArr.each(function(el) { message += '&mdash; ' + el + '<br />'; });

			// show message
			this.roar.alert(header, message);
		}
	},
	//--------------------------------------------------------------------------------
	element: {
		addClassAll: function(parentEl, className) {
			$(parentEl).addClass(className);
			$(parentEl).getChildren('div').each(function(childEl) { childEl.addClass(className); });
			$(parentEl).getChildren('span').each(function(childEl) { childEl.addClass(className); });
		},
		//--------------------------------------------------------------------------------
		removeClassAll: function(parentEl, className) {
			$(parentEl).removeClass(className);
			$(parentEl).getChildren('div').each(function(childEl) { childEl.removeClass(className); });
			$(parentEl).getChildren('span').each(function(childEl) { childEl.removeClass(className); });
		},
		//--------------------------------------------------------------------------------
		show: function(el) {
			$(el).setStyle('display', '');
		},
		//--------------------------------------------------------------------------------
		hide: function(el) {
			$(el).setStyle('display', 'none');
		},
		//--------------------------------------------------------------------------------
		showGroup: function(groupId, parentEl) {
			// params
			parentEl = $($pick(parentEl.body, document.body));

			// show all elements with groupId within the parentEl element
			parentEl.getElements('[group=' + groupId + ']').each(function(el) { core.element.show(el); });

		},
		//--------------------------------------------------------------------------------
		hideGroup: function(groupId, parentEl) {
			// params
			parentEl = $($pick(parentEl.body, document.body));

			// hide all elements with groupId within the parentEl element
			parentEl.getElements('[group=' + groupId + ']').each(function(el) { core.element.hide(el); });
		}
	},
	//--------------------------------------------------------------------------------
	browser: {
		//--------------------------------------------------------------------------------
		open: function(url) {
			document.location = url;
		},
		//--------------------------------------------------------------------------------
		reload: function(url) {
			document.location = document.location;
		},
		//--------------------------------------------------------------------------------
		popup: function(url, width, height) {
			// init args
			width = $pick(width, 750);
			height = $pick(height, 500);

			// create popup
			var elPopup = new Element('div', {
				'id': 'popup',
				'class': 'popup-wrapper',
				'html': '<div id="popup_nav" class="popup-nav"><input type="button" value="close" class="input-button" style="float:right;margin:2px;" onclick="core.overlay.hide(\'popupoverlay\');$(\'popup\').destroy();" onmouseover="$(this).addClass(\'hover-button\');" onmouseout="$(this).removeClass(\'hover-button\');" /></div><div id="popup_content" class="popup-content" style="height:' + (height - 35) + 'px"></div>',
				'styles': {
					'top': '50%',
					'left': '50%',
					'width': width + 'px',
					'height': height + 'px',
					'margin-top': '-' + (height / 2) + 'px',
					'margin-left': '-' + (width / 2) + 'px'
				}
			});

			// view popup
			core.overlay.show('panel_body', 'popupoverlay')
			elPopup.inject('panel_body', 'before');
			core.ajax.requestUpdate(url, 'popup_content');
		}
		//--------------------------------------------------------------------------------
	},
	///--------------------------------------------------------------------------
	html: {
	  	e_hex: function(event) { // event->onkeypress: limit to hex chars 0-9 and A-F
		  	// convert a-f to A-F
		  	if (event.keyCode >= 97 && event.keyCode <= 102) event.keyCode -=32;

		  	if ((event.keyCode >= 48 && event.keyCode <= 57) || (event.keyCode >= 65 && event.keyCode <= 70)) return true;
		  	else return false;
	  	},
		///--------------------------------------------------------------------------
	  	e_alphanum: function(event) { // event->onkeypress limit to chars a-zA-Z0-9
		  	if ((event.keyCode >= 48 && event.keyCode <= 57) || (event.keyCode >= 65 && event.keyCode <= 90) || (event.keyCode >= 97 && event.keyCode <= 122)) return true;
		  	else return false;
	 	},
	 	///--------------------------------------------------------------------------
	  	e_numeric: function(event) { // event->onkeypress: limit to chars 0-9
		  	if (event.keyCode >= 48 && event.keyCode <= 57) return true;
		  	else return false;
	 	},
		///--------------------------------------------------------------------------
		e_fraction: function(event) { // event->onkeypress: limit to chars 0-9 and .
	  		if ((event.keyCode >= 48 && event.keyCode <= 57) || (event.keyCode == 46)) return true;
		  	else return false;
		},
		///--------------------------------------------------------------------------
		e_date: function(event) { // event->onkeypress: limit to chars 0-9 and -
		  	if ((event.keyCode >= 48 && event.keyCode <= 57) || (event.keyCode == 45)) return true;
		  	else return false;
		},
		///--------------------------------------------------------------------------
		e_contact: function(event) { // event->onkeypress limit to chars 0-9 and +[space]
		  	if ((event.keyCode >= 48 && event.keyCode <= 57) || (event.keyCode == 43) || (event.keyCode == 32)) return true;
		  	else return false;
		},
		///--------------------------------------------------------------------------
		e_email: function(event) { // event->onkeypress limit to chars a-zA-Z0-9 and @.
		  	if ((event.keyCode >= 48 && event.keyCode <= 57) || (event.keyCode >= 64 && event.keyCode <= 90) || (event.keyCode >= 97 && event.keyCode <= 122) || (event.keyCode == 95) || (event.keyCode == 45) || (event.keyCode == 46)) return true;
		  	else return false;
		},
		///--------------------------------------------------------------------------
		e_url: function(event) { // event->onkeypress limit to chars a-zA-Z0-9 and @.
		  	if ((event.keyCode >= 45 && event.keyCode <= 57) || (event.keyCode >= 64 && event.keyCode <= 90) || (event.keyCode >= 97 && event.keyCode <= 122) || (event.keyCode == 95)) return true;
		  	else return false;
		},
		///--------------------------------------------------------------------------
		e_nospace: function(event) { // event->onkeypress limit anything except spaces
		  	if (event.keyCode == 32) return false;
		  	else return true;
		}
		///--------------------------------------------------------------------------
	}
	///--------------------------------------------------------------------------
}
//--------------------------------------------------------------------------------
var cr = { // core framework
	///--------------------------------------------------------------------------
	cache: { // temporary storage
	},
	///--------------------------------------------------------------------------
	element: { // manipulates elements
	  	///--------------------------------------------------------------------------
	  	over: function(the_element) { // adds '-hover' to element's class name
		    var the_element = $(the_element);
		    var over_signature = the_element.className.substr(the_element.className.length-6, 6);
		    if (over_signature != '-hover') the_element.className = the_element.className + '-hover';
	  	},
		///--------------------------------------------------------------------------
	  	out: function(the_element) { // removes '-hover' from element's class name
		    var the_element = $(the_element);
		    var over_signature = the_element.className.substr(the_element.className.length-6, 6);
		    if (over_signature == '-hover') the_element.className = the_element.className.slice(0, the_element.className.length-6);
		},
		///--------------------------------------------------------------------------
		hide: function (the_element) { // hide element
		    var the_element = $(the_element);
		    if (the_element)
				if (the_element.style.display != 'none') the_element.style.display = 'none';
		},
		///--------------------------------------------------------------------------
		show: function (the_element, the_style) { // show element
			if (the_style == null) the_style = 'block';
		    var the_element = $(the_element);
		    if (the_element)
		    	if (the_element.style.display != the_style) the_element.style.display = the_style;
		},
		///--------------------------------------------------------------------------
		toggle: function (the_element, the_style) { // toggle element visibility
			if (the_style == null) the_style = 'block';
		    var the_element = $(the_element);
		    if (the_element) {
				if (the_element.style.display == the_style || the_element.style.display == null) cr.element.hide(the_element);
				else cr.element.show(the_element, the_style);
		    }
		}
		///--------------------------------------------------------------------------
	},
	///--------------------------------------------------------------------------
	nav : { // manipulate browser
		popup_count: 0, // keep track of how many popups created
		///--------------------------------------------------------------------------
		submit: function(the_form, the_url, the_message, the_onsubmit) { // Gives the user a confirmation box before submitting the form to an url
		  	var proceed = (the_message == null ? true : window.confirm(the_message));
		  	if (proceed) {
		  	  	var the_form = document.forms[the_form];
		  	  	if (the_url != null) the_form.action = the_url;
		  	  	if (the_onsubmit != null) the_form.onsubmit = the_onsubmit;
		  	  	var proceed = (the_form.onsubmit == null ? true : the_form.onsubmit());
		  	  	if (proceed) the_form.submit();
			}
		},
		///--------------------------------------------------------------------------
		popup: function(the_url, the_width, the_height, the_position, the_scrollbars) { // opens an url in a new popup
		  	// init defaults
		  	var the_width = (the_width == null ? 'max' : the_width);
		  	var the_height = (the_height == null ? 'max' : the_height);
		  	var the_position = (the_position == null ? 'none' : the_position);
		  	var the_scrollbars = (the_scrollbars == null ? 'yes' : the_scrollbars);

		    // keep track of how many popups where opened
		    cr.nav.popup_count++;

		    // convert 'max' meta to maximum value
		    if (the_width == 'max') the_width = window.screen.width-10;
		    if (the_height == 'max') the_height = window.screen.height-120;

		    // create window
		    var the_popup = window.open(the_url ,'cr_popup_' + cr.nav.popup_count,'toolbar=no,status=yes,resizable=yes,directories=no,location=no,menubar=no,scrollbars='+the_scrollbars+',width='+the_width+',height='+the_height);

		    // movie window to specified position
		    if (the_position != 'none') {
			    var start_x = 0;
			    var start_y = 0;
			    switch (the_position) {
			      	case 'right'  : start_x = Math.floor(window.screen.width - the_width - 10); break;
			      	case 'center' :
						start_x = Math.floor(window.screen.width / 2 - the_width / 2);
			    		start_y = Math.floor(window.screen.height / 2 - the_height / 2);
			    		break;
			    }
			    the_popup.moveTo(start_x, start_y);
		    }
		},
		///--------------------------------------------------------------------------
		popup_image: function(the_image, the_image_name, the_width, the_height) { // opens an image in a new popup
		    // keep track of how many popups where opened
		    cr.nav.popup_count++;

		    // Scale image to fit on user's screen
		    var max_width = window.screen.width-10;
		    var max_height = window.screen.height-120;
		    if (the_width > max_width) {
		        the_height = Math.floor((max_width / the_width) * the_height);
		        the_width = the_width;

		    }
		    if (the_height > max_height) {
		        the_width = Math.floor((max_height / the_height) * the_width);
		        the_height = max_height;
		    }

		    // Create window
		    image_window = window.open('', 'cr_popup_'+cr.nav.popup_count, 'toolbar=no,status=no,resizable=no,directories=no,location=no,menubar=no,scrollbars=no,width='+the_width+',height='+the_height);
		    image_window.document.writeln('<html>');
		    image_window.document.writeln('<head><title>'+the_image_name+'</title></head>');
		    image_window.document.writeln('<style type="text/css">body { font: 12px Arial; color: #696969; margin: 0px; padding: 0px; background-color: #FFFFFF; }</style>');
		    image_window.document.writeln('<body><img src="'+the_image+'" width="'+the_width+'" height="'+the_height+'" /></body>');
		    image_window.document.writeln('</html>');

		    // Move window to center of screen
		    var start_x = Math.floor(window.screen.width / 2 - the_width / 2);
		    var start_y = Math.floor(window.screen.height / 2 - the_height / 2);
		    image_window.moveTo(start_x, start_y);
		}
		///--------------------------------------------------------------------------
	},
	///--------------------------------------------------------------------------
	string: { // manipulate strings
	  	///--------------------------------------------------------------------------
	  	password: function(the_length) { // generate a random set(0-9a-zA-Z) of characters
		  	var the_password = '';
		  	for (i = 0; i < the_length; i++) {
		  	  	var the_charcode = $random(0, 62);

				var the_charoffset = 48; // 0..9
				if (the_charcode > 9) the_charoffset += 7; // A..Z
				if (the_charcode > 35) the_charoffset += 6; // a..z

				the_charcode += the_charoffset;

				the_password += String.fromCharCode(the_charcode);
			}
			return the_password;
	  	}
	  	///--------------------------------------------------------------------------
	}
	///--------------------------------------------------------------------------
}
///--------------------------------------------------------------------------
function $$getvalue(the_element_id, the_value) { // get the value of a given element and/or set a new one
  	var the_element = $(the_element_id);
  	var return_value = the_value;

  	if (!the_element) return; // element not found

  	if (the_value != null) { // set new value
	  	if (the_element.type != null) the_element.value = the_value; // input tag
	  	else if (the_element.innerHTML != null) the_element.innerHTML = the_value; // default html element
	}
	else { // get value
	  	if (the_element.type != null) { // input tag
	  		switch (the_element.type) {
	  		  	case 'select-one' 	: return_value = the_element.options[the_element.selectedIndex].value; break;
	  		  	default 			: return_value = the_element.value; break;
	  		}
	  	}
	  	else if (the_element.innerHTML != null) return_value = the_element.innerHTML; // default html element
	}

  	return return_value;
}
///--------------------------------------------------------------------------
