
  /**
	* procore.api.js
	* @author  	   Adam Lee - ejectcore.com
	* @copyright   Copyright Eject Core 2010-2011. All rights reserved.
	* @license 	   end-user license agreements (EULAs)
	* @package     Pro Core Manager API
	* @version 	   1.1 Final
	*
	*/	
	
	function ucfirst(str) {
	    var firstLetter = str.substr(0, 1);
	    return firstLetter.toUpperCase() + str.substr(1);
	}	
	
	var proCoreApi = (function() {
		
		(function($$) {
			$$.fn.typeWatch = function(options){
	
				options = $$.extend({
					wait           : 800,
					callback       : function() {},
					requiredLength : 0
				}, options);
				
				function checkElement(timer, override) {
					var elTxt = $$(timer.el).val();
					if((elTxt.length >= options.requiredLength && elTxt.toUpperCase() != timer.text) || (override && elTxt.length >= options.requiredLength)) {
						timer.text = elTxt.toUpperCase();
						timer.cb(elTxt);
					}
				};
				
				function watchElement(element) {
					if(element.type != undefined) {
						if(element.type.toUpperCase() == "TEXT" || element.nodeName.toUpperCase() == "TEXTAREA") {
							
							var timer = {
								timer : null, 
								text  : $$(element).val().toUpperCase(),
								cb    : options.callback, 
								el    : element, 
								wait  : options.wait
							};
		
							var startWatch = function(event) {
								var timerWait    = timer.wait;
								var overrideBool = false;
								
								if(event.keyCode == 13 && this.type.toUpperCase() == "TEXT") {
									timerWait    = 1;
									overrideBool = true;
								}
								
								var timerCallbackFx = function() {
									checkElement(timer, overrideBool)
								}
								$$(element).listenForChange();
	
								clearTimeout(timer.timer);
								timer.timer = setTimeout(timerCallbackFx, timerWait);					
							};
							$$(element).bind('keydown change click', startWatch);
						}
					}
				};
	
				return this.each(function(index){
					watchElement(this);
				});
	
			};
		})($$);
		
		(function($$) {
			$$.fn.listenForChange = function(options) {
				settings = $$.extend({
					interval: 100 // in microseconds
				}, options);
				
				var jquery_object = this;
				var current_focus = null;
				
				jquery_object.filter(":input").add(":input", jquery_object).focus( function() {
					current_focus = this;
				}).blur( function() {
					current_focus = null;
				});
				
				setInterval(function() {
					// allow
					jquery_object.filter(":input").add(":input", jquery_object).each(function() {
					    // set data cache on element to input value if not yet set
					    if ($$(this).data('change_listener') == undefined) {
					        $$(this).data('change_listener', $$(this).val());
					        return;
					    }
					    // return if the value matches the cache
					    if ($$(this).data('change_listener') == $$(this).val()) {
					        return;
					    }
					    // ignore if element is in focus (since change event will fire on blur)
					    if (this == current_focus) {
					        return;
					    }
					    // if we make it here, manually fire the change event and set the new value
					    $$(this).trigger('change');
					    $$(this).data('change_listener', $$(this).val());
					});
				}, settings.interval);
				return this;
			};
		})($$);
	
		var globalScope    = {};
		var requiredLength = 3;
		var apiTools = {
			elementEffect : function() {},
			elementStatus : function(element, required, onSuccess) {
				fieldLength = (required === true ? requiredLength : 0);
				if(element.attr('type') == 'text' || element.attr('type') == 'textarea') {
					if(element.val() != '' && element.val().length >= fieldLength && onSuccess == true) {
						element.addClass('success').removeClass('required error').prev('span').removeClass('errorIcon').addClass('successIcon');
					} else {
						element.removeClass('success').addClass('error').prev('span').removeClass('successIcon').addClass('errorIcon');
						if(element.val().length == 0) element.removeClass('error').prev('span').removeClass('errorIcon');
						if(required == true) element.addClass('required');
					}
				} else if(element.attr('type') == 'select-one') {
					if(element.val() > 0 && onSuccess == true) {
						element.addClass('success').removeClass('required').prev('span').addClass('successIcon');
					} else {
						element.removeClass('success').prev('span').removeClass('successIcon');
						if(required == true) element.addClass('required');
					}
				} else {
					if(element.attr('class') == 'radio')
						element.prev('span').addClass('successIcon');
				}
			}
		};
		
		var apiAjaxMethod = {
			bindEvent    : function(selector, eventObj, data, method, response){
				if(typeof(eventObj) == 'object' && eventObj.plugin == 'typeWatch') {
					$$(selector).typeWatch({ wait : eventObj.wait, callback : function() {
						$obj = $$(this.el);
						
						if(eventObj.hasOwnProperty('bindValue'))
							eventObj.bindValue(data, $obj);
						if(eventObj.hasOwnProperty('execute'))
							eventObj.execute(data, $obj);
						if(! eventObj.hasOwnProperty('validate') || eventObj.validate($obj) !== false) {
		 		      	apiAjaxMethod.switchMethod(data, $obj, method, response);
		 		      }
	 		      }});
				} else {
					var executeEventObj = function(obj) {
						if(eventObj.hasOwnProperty('bindValue'))
							eventObj.bindValue(data, obj);
						if(eventObj.hasOwnProperty('execute'))
							if(eventObj.execute(data, obj) !== true)
								return false;
						if(method != undefined)
							apiAjaxMethod.switchMethod(data, obj, method, response);
					};
					if(eventObj.event !== undefined && eventObj.event.substr(0, 3) == 'key') {
						$$(selector).live(eventObj.event, function() {
							executeEventObj($$(this));
						});
					} else {
						var event = eventObj;
						if(eventObj.hasOwnProperty('event'))
							event = eventObj.event;
						if(eventObj.event != 'change') {
							$$(selector).live(event, function() {						
								executeEventObj($$(this));
								if(eventObj.type != 'radio' && (event == 'click' || event == 'submit'))
									return false;
							});
						} else {
							// Live Change Event Not Supported by IE!
							if(! $.browser.msie) {
								$$(selector).live('change', function() { executeEventObj($$(this)); });
							} else {
								$$(selector).change(function() { executeEventObj($$(this)); });
							}
						}
					}
				}
			},
			switchMethod : function(data, obj, method, response) {
				if(response !== false) {
					this.onBind = true;
					switch(method) {
						case 'getJSON' :
							this.getJSON(data, obj, response);
							break;
						case 'ajax' :
							this.ajax(data, obj, response);
							break;
						case 'get' :
							this.get(data, obj, response);
							break;
						case 'post' :
							this.post(data, obj, response);
							break;
					}
				}		
			},
			defaultData  : {},
			method       : false,
			onBind       : false,
			resetData    : function(data) {
				for(var key in data)
				  if(data.hasOwnProperty(key))
				    delete(data[key]);	
			},
			ajaxSetup    : function() {
				$.ajaxSetup({
	 				cache: false,
	 				async: false
				});
			},
			getJSON      : function(data, obj, response){
				this.method   = 'getJSON';
				data = $$.extend(this.defaultData, data);
				if(response !== false) {
					$.getJSON(responder, data, function(json) {
						if(json.success) {
							if(response != null) {
								if(response.hasOwnProperty('onSuccess')) {
									response.onSuccess(json, obj);
								}
							}
						} else {
							if(response != null) {
								if(response.hasOwnProperty('onError')) {
									response.onError(json, obj);
								}
							}
						}
						apiAjaxMethod.resetData(data);
					});
				}
			},
			ajax         : function(data, response){ 
				this.method   = 'ajax';
				this.dataObj  = $$.extend(this.defaultData, dataObj);
				this.response = response;
			},
			get          : function(data, response){ 
				this.method   = 'get';
				this.dataObj  = $$.extend(this.defaultData, dataObj);
				this.response = response;
			},
			post         : function(data, getParams, response, dataType){ 
				this.method   = 'post';
				data = $$.extend(this.defaultData, data);
				$.post(responder + getParams, data , function(data) {
					if(data.success) {
						if(response.hasOwnProperty('onSuccess')) {
							response.onSuccess(data);
						}
					} else {
						if(response.hasOwnProperty('onError')) {
							response.onError(data);
						}
					}
					apiAjaxMethod.resetData(data);
				}, dataType);
			}
		};
		
		var apiSystemMsg = {
			'error'   : '[default error message]',
			'success' : '[default success message]',
			'warning' : '[default warning message]'
		};
		
		var coremanager = {
			interface    : function(module){}
		};
		
		var pluginExtendObj = {};
		
		return {
			init: function() {
				apiAjaxMethod.ajaxSetup();
				return apiObj = {
					tools      : apiTools,
					systemMsg  : apiSystemMsg,
					ajaxMethod : apiAjaxMethod,
					pluginExt  : pluginExtendObj
				};
			}
		};
		
	})();
	
	// Initialise the API
	var api = proCoreApi.init();
