/**
 * This is our version of indexOf to make it work in IE
 */
if(!Array.indexOf){
    Array.prototype.indexOf = function(obj){
        for(var i=0; i<this.length; i++){
            if(this[i]==obj){
                return i;
            }
        }
        return -1;
    }
}


/*
 * Trims the string on both sides
 */
String.prototype.trim = function() {
	return this.replace(/^\s+|\s+$/g, "");
}

/*
 * Replace all occurances of stringToFind with stringToReplace
 */
String.prototype.replaceAll= function(stringToFind,stringToReplace){
	var temp = this.toString();
	var index = temp.indexOf(stringToFind);
	
	while(index != -1){
		temp = temp.replace(stringToFind,stringToReplace);
		index = temp.indexOf(stringToFind);
	}
	
	return temp;
}

String.prototype.replaceAllRegex = function(regex, replaceString){
	var temp = this.toString();
	var index = temp.search(regex);
	
	while(index != -1){
		temp = temp.replace(regex,replaceString);
		index = temp.search(regex);
	}
	
	return temp;
}

String.prototype.reverse = function() {
	revStr = '';
	for (var i=this.length-1;i>=0;i--){
		revStr += this.charAt(i); 
	}
	
	return revStr;
}
//
String.prototype.sanitize = function(){
	var filters = [
	               new RegExp("<script[^>]*?>.*", "i"), 
	               new RegExp("<[\/\!]*?[^<>]*?>", "i")
	               ];
	var cleaned = this.toString();
	for (var i=0;i<filters.length;i++){
		cleaned = cleaned.replaceAllRegex(filters[i], "");
	}
	
	return cleaned;
}

Array.prototype.find = function(searchStr) {
  var returnArray = false;
  for (i=0; i<this.length; i++) {
    if (typeof(searchStr) == 'function') {
      if (searchStr.test(this[i])) {
        if (!returnArray) { returnArray = [] }
        returnArray.push(i);
      }
    } else {
      if (this[i]===searchStr) {
        if (!returnArray) { returnArray = [] }
        returnArray.push(i);
      }
    }
  }
  return returnArray;
}

/**
 * This method serializes any jQuery object into a well-formatted
 * JSON object
 */

$.fn.serializeObject = function()
{
    var o = {};
    var a = this.serializeArray();
    $.each(a, function() {
        if (o[this.name]) {
            if (!o[this.name].push) {
                o[this.name] = [o[this.name]];
            }
            o[this.name].push(this.value || '');
        } else {
            o[this.name] = this.value || '';
        }
    });
    return o;
};

/*
 * Assuming that str is a string of numbers ONLY (No , or . allowed)
 * It puts commas (,) at every third character
 */
function formatCurrency(str){
	if(str.length <= 3) 
		return str;
	
	var formattedStr = '';
	var remainder = str.length%3;
	
	if (remainder > 0){
		formattedStr += str.substring(0,remainder) + ',';
		str = str.substring(remainder);
	}
	
	var numSections = str.length/3;
	
	for (var i=0;i<numSections;i++){
		formattedStr += str.substring(i*3, i*3+3);
		if (i != numSections-1){
			formattedStr += ',';
		}
	}
	
	return formattedStr;
}

/*
 * Very similar to formatCurrency function, but this is a prototype of Number
 */
Number.prototype.formatMoney = function(c, d, t){
	var n = this, c = isNaN(c = Math.abs(c)) ? 2 : c, d = d == undefined ? "," : d, t = t == undefined ? "." : t, s = n < 0 ? "-" : "", i = parseInt(n = Math.abs(+n || 0).toFixed(c)) + "", j = (j = i.length) > 3 ? j % 3 : 0;
    return s + (j ? i.substr(0, j) + t : "") + i.substr(j).replace(/(\d{3})(?=\d)/g, "$1" + t) + (c ? d + Math.abs(n - i).toFixed(c).slice(2) : "");
}

/*
 * Merges two json objects together
 */
function mergeObjects (o, ob) {
	var i = 0;
	for (var z in ob) {
		if (ob.hasOwnProperty(z)) {
			o[z] = ob[z];
		}
	}
	return o;
}

function tokenInputLocalSearch(query, dataContainer) {
	var output = new Array();
	var regEx = new RegExp(query, "i");
	for ( var i = 0; i < dataContainer.length; i++) {
		if (dataContainer[i].name.search(regEx) >= 0) {
			output.push(dataContainer[i]);
			if (output.length == 10)
				break;
		}
	}
	return output;
}

function isdefined(variable){
    return (typeof(window[variable]) == "undefined")?  false: true;
}

function loadDynamicResource(filename, filetype) {
	if (filetype == "js") { // if filename is a external JavaScript file
		var fileref = document.createElement('script');
		fileref.setAttribute("type", "text/javascript");
		fileref.setAttribute("src", filename);
	} else if (filetype == "css") { // if filename is an external CSS file
		var fileref = document.createElement("link");
		fileref.setAttribute("rel", "stylesheet");
		fileref.setAttribute("type", "text/css");
		fileref.setAttribute("href", filename);
	}
	if (typeof fileref != "undefined")
		document.getElementsByTagName("head")[0].appendChild(fileref);
}

function findPos(obj) {
	var curleft = curtop = 0;
	if (obj.offsetParent) {
		do {
			curleft += obj.offsetLeft;
			curtop += obj.offsetTop;
		} while (obj = obj.offsetParent);
		return [curleft,curtop];
	}
}

function openModal(title, message, allowClose){
	
	allowClose = (allowClose == null); 
	
	// remove all old modal boxes generated
	$('#modal').remove();
	
	var closeButton = "";
	// build modal box according to specs
	if (allowClose){
		closeButton = "<a onclick='closeModal()' style='float: right; margin-top: -10px'><img src='/scripts/highslide-graphics/close.png'/></a>";
	}else{
		closeButton = "";
	}
	
	var modalHtml = "<div id='modal'><div><h2 style='font-size: 14px; padding-top: 10px;'>"+title+closeButton+"</h2><p style='font-size: 12px; margin-top: 15px; min-height: 25px'>"+message+"</p></div></div>";
	
	// append a new modal box to the page
	$('body').append(modalHtml);
	
	// enable and configure the overlay
	$('#modal').overlay({
		// custom top position
		top: 260,

		// some mask tweaks suitable for facebox-looking dialogs
		mask: {

			// you might also consider a "transparent" color for the mask
			color: '#fff',

			// load mask a little faster
			loadSpeed: 200,

			// very transparent
			opacity: 0.7
		},

		// disable this for modal dialog-type of overlays
		closeOnClick: false,
		closeOnEsc: false,
		
		// close button
		close: 'dingus',
		
		top: '20%'
	});
	
	// open the modal through the API
	var api = $('#modal').data('overlay');
	api.load();
	
}

function closeModal(){
	var api = $('#modal').data('overlay');
	api.close();
}


//This function returns the name of a given function. It does this by
//converting the function to a string, then using a regular expression
//to extract the function name from the resulting code.
function funcname(f) {
 var s = f.toString().match(/function (\w*)/)[1];
 if ((s == null) || (s.length == 0)) return "anonymous";
 return s;
}

//This function returns a string that contains a "stack trace."
function stacktrace() {
 var s = "";  // This is the string we'll return.
 // Loop through the stack of functions, using the caller property of
 // one arguments object to refer to the next arguments object on the
 // stack.
 for(var a = arguments.caller; a != null; a = a.caller) {
     // Add the name of the current function to the return value.
     s += funcname(a.callee) + "\n";

     // Because of a bug in Navigator 4.0, we need this line to break.
     // a.caller will equal a rather than null when we reach the end 
     // of the stack. The following line works around this.
     if (a.caller == a) break;
 }
 return s;
}

function printStackTrace() {
  var callstack = [];
  var isCallstackPopulated = false;
  try {
    i.dont.exist+=0; //doesn't exist- that's the point
  } catch(e) {
    if (e.stack) { //Firefox
      var lines = e.stack.split('\n');
      for (var i=0, len=lines.length; i<len; i++) {
        if (lines[i].match(/^\s*[A-Za-z0-9\-_\$]+\(/)) {
          callstack.push(lines[i]);
        }
      }
      //Remove call to printStackTrace()
      callstack.shift();
      isCallstackPopulated = true;
    }
    else if (window.opera && e.message) { //Opera
      var lines = e.message.split('\n');
      for (var i=0, len=lines.length; i<len; i++) {
        if (lines[i].match(/^\s*[A-Za-z0-9\-_\$]+\(/)) {
          var entry = lines[i];
          //Append next line also since it has the file info
          if (lines[i+1]) {
            entry += " at " + lines[i+1];
            i++;
          }
          entry = entry + "\n";
          callstack.push(entry);
        }
      }
      //Remove call to printStackTrace()
      callstack.shift();
      isCallstackPopulated = true;
    }
  }
  if (!isCallstackPopulated) { //IE and Safari
    var currentFunction = arguments.callee.caller;
    while (currentFunction) {
      var fn = currentFunction.toString();
      var fname = fn.substring(fn.indexOf("function") + 8, fn.indexOf('')) || 'anonymous';
      callstack.push(fname);
      currentFunction = currentFunction.caller;
    }
  }
  output(callstack);
}

function output(arr) {
  //Optput however you want
}

function fireNativeJsEvent(element, eventName, ieEventName){
	var event;
	if (document.createEvent) {
		event = document.createEvent("HTMLEvents");
		event.initEvent(eventName, true, true);
	} else {
		event = document.createEventObject();
		event.eventType = ieEventName;
	}
	
	event.eventName = eventName;
//	event.memo = memo || { };
	
	if (document.createEvent) {
		element.dispatchEvent(event);
	} else {
		element.fireEvent(event.eventType, event);
	}
}

// This function is used for when the user presses the 'Enter' key while filling out a form
// and will submit that form alone
function submitenter(myfield,e) {
	var keycode;
	if (window.event) keycode = window.event.keyCode;
	else if (e) keycode = e.which;
	else return true;
	
	if (keycode == 13)
	   {
	   myfield.form.submit();
	   return false;
	   }
	else
	   return true;
}

function loadPngForIe6(img) {
	if (	img != null &&
			navigator.platform == "Win32" && 
			navigator.appName == "Microsoft Internet Explorer"){
		
		var rslt = navigator.appVersion.match(/MSIE (\d+\.\d+)/, '');
		var itsAllGood = (rslt != null && Number(rslt[1]) >= 5.5);
		
		if (itsAllGood){
			img.style.display = "none";
			var src = img.src;
			var div = document.createElement("DIV");
			div.style.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='" + src + "', sizing='scale')";
			div.style.width = img.width + "px";
			div.style.height = img.height + "px";
			img.replaceNode(div);
		}
	}
}

function runningInIE(){
	return navigator.appName == "Microsoft Internet Explorer";
}

function setupEventsForDefaultValueOf(id, formatFunction){
	var elem = $('#'+id);
	if (elem.length != 1){
		return;
	}
	var defaultValue = elem.attr('defaultValue');
	elem.blur(
			function() {
			var curValue = this.value.trim(); 
			if (curValue == '' || curValue == defaultValue){
				this.value = defaultValue;
				//$(this).removeClass('nonDefaultValue');
				$(this).addClass('defaultValue');
			}else{
				if (formatFunction != null){
					$(this).removeClass('DefaultValue');
					//$(this).addClass('nonDefaultValue');
					formatFunction(id);
				}
			}
		}
	);
	
	elem.focus(
			function() {
			if (this.value.trim() == defaultValue){ 
				this.value = '';
				$(this).removeClass('defaultValue');
				//$(this).addClass('nonDefaultValue');
			}
		}
	);
}

function setupEventsForSanitizingValueOf(id){
	var elem = $('#'+id);
	elem.blur(
			function(){
				elem = $(this);
				elem.val(elem.val().sanitize());
			}
	);
}

//Grayscale w canvas method
function grayscale(src){
    var canvas = document.createElement('canvas');
	var ctx = canvas.getContext('2d');
    var imgObj = new Image();
	imgObj.src = src;
	canvas.width = imgObj.width;
	canvas.height = imgObj.height; 
	ctx.drawImage(imgObj, 0, 0); 
	var imgPixels = ctx.getImageData(0, 0, canvas.width, canvas.height);
	for(var y = 0; y < imgPixels.height; y++){
		for(var x = 0; x < imgPixels.width; x++){
			var i = (y * 4) * imgPixels.width + x * 4;
			var avg = (imgPixels.data[i] + imgPixels.data[i + 1] + imgPixels.data[i + 2]) / 3;
			imgPixels.data[i] = avg; 
			imgPixels.data[i + 1] = avg; 
			imgPixels.data[i + 2] = avg;
		}
	}
	ctx.putImageData(imgPixels, 0, 0, 0, 0, imgPixels.width, imgPixels.height);
	return canvas.toDataURL();
}

function fadeImageIn(img){
	$(img).fadeIn('slow')
}

function searchById(targetId, collection){
	for (var i=0;i<collection.length;i++){
		var item = collection[i];
		if (item['id'] == targetId){
			return item['name'];
		}
	}
}


/***
 * VERY IMPORTANT FUNCTION: 
 * if firebug or similar is not open on the browser, just ignore calls to console.log
 */
if (window.console === undefined){
	console = new Object()
	console.log = function(){}
}
