// See http://blogs.msdn.com/xmlteam/archive/2006/10/23/using-the-right-version-of-msxml-in-internet-explorer.aspx
// If you are curious why the XMLHTTP versions specified are and why others are not.
var ajax_call_counter = 0;

//  copies stringVal to the clipboard
function toClipboard(stringVal,hideAlert)
{
  if (window.clipboardData)     //  internet explorer
    window.clipboardData.setData("Text", stringVal);
  else if (window.netscape)     //  netscape, mozilla, firefox, and derivitives
  {
    try {
      netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
    }
    catch(e) {
      alert('Please type "about:config" in your browser and press enter. Type "signed.applets.codebase_principal_support" in Filter. Double click to change the value to "true". Then come back and click on the link again.\n\nIf you have already performed this action, make sure when you are asked whether to allow or deny the browser permission, that you are allowing it.');
      return;
    }
    // get a clipboard object
    var clip = Components.classes['@mozilla.org/widget/clipboard;1'].createInstance(Components.interfaces.nsIClipboard);
    if (!clip)
    {
      alert("Error 1");
      return;
    }
    // get a transferable object
    var trans = Components.classes['@mozilla.org/widget/transferable;1'].createInstance(Components.interfaces.nsITransferable);
    if (!trans)
    {
      alert("Error 2");
      return;
    }
    // we only want to copy text
    trans.addDataFlavor('text/unicode');

    var str = new Object();
    var len = new Object();
    var str = Components.classes["@mozilla.org/supports-string;1"].createInstance(Components.interfaces.nsISupportsString);
    var copytext = stringVal;

    str.data = copytext;
    trans.setTransferData("text/unicode",str,copytext.length*2);
    var clipid=Components.interfaces.nsIClipboard;
    if (!clip)
    {
      alert("Error 3");
      return;
    }
    clip.setData(trans,null,clipid.kGlobalClipboard);
  }

  if (!hideAlert) alert("The link has been copied to your clipboard.");
  return true;
}

function getClipboard() {
  if (window.clipboardData) {
    //MSIE
    return(window.clipboardData.getData('Text'));
  } else if (window.netscape) {
    //Mozilla Firefox
    try {
      netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
    }
    catch(e) {
      alert('Please type "about:config" in your browser and press enter. Type "signed.applets.codebase_principal_support" in Filter. Double click to change the value to "true". Then come back and click on the link again.\n\nIf you have already performed this action, make sure when you are asked whether to allow or deny the browser permission, that you are allowing it.');
      return;
    }
    var clip = Components.classes['@mozilla.org/widget/clipboard;1'].createInstance(Components.interfaces.nsIClipboard);
    if (!clip) return;
    var trans = Components.classes['@mozilla.org/widget/transferable;1'].createInstance(Components.interfaces.nsITransferable);
    if (!trans) return;
    trans.addDataFlavor('text/unicode');

    var str = new Object();
    var len = new Object();
    clip.getData(trans, clip.kGlobalClipboard);
    try { trans.getTransferData('text/unicode', str, len); }
    catch(error) { return; }
    if (str) {
      if (Components.interfaces.nsISupportsWString) str=str.value.QueryInterface(Components.interfaces.nsISupportsWString);
      else if (Components.interfaces.nsISupportsString) str=str.value.QueryInterface(Components.interfaces.nsISupportsString);
      else str = null;
    }
    if (str) return(str.data.substring(0, len.value/2));
  }
  return;
}

//countdown to Christmas would be - countdown_clock(2007, 12, 25, 00, 00, 1);
function countdown_clock(year, month, day, hour, minute, format) {
	html_code = '<div id="countdown"></div>';
	document.write(html_code);
	countdown(year, month - 1, day, hour, minute, format);
}

//Pads the left of a string.
function LPad(string, chr, num) {
	string += '';

	if (string.length < num) {
		var buffer = ""; 
		for(var i = 0; i < num - string.length; i++)
			buffer += chr;
		return buffer + string;
	} 
	else
		return string;
}

//Combines date and time into a castable SQL date.
function FormatSQLDate(theDate, theTime, theAMPM) {
  var s = new String(); var arrDate = new Array(); var arrTime = new Array();

  s = theDate; arrDate = s.split('/');
  s = theTime; arrTime = s.split(':');
  s = theAMPM; s = s.toLowerCase();

  if (s == "pm" && parseInt(arrTime[0]) < 12) { arrTime[0] = (parseInt(arrTime[0]) + 12) + ''; }
  if (s == "am" && arrTime[0] == "12") { arrTime[0] = "00"; }
  return (LPad(arrDate[0],'0',2) + '/' + LPad(arrDate[1],'0',2) + '/' + arrDate[2] + " " + LPad(arrTime[0],'0',2) + ":" + LPad(arrTime[1],'0',2) + ":00");
}

function countdown(year, month, day, hour, minute, format) {
	var Today = new Date();
	var Target = new Date(year, month, day, hour, minute, 0, 0);
	var elemCountDown = document.getElementById('countdown');

	//Convert both todays date and the target date into miliseconds.
	var Todays_Date = Today.getTime();
	var Target_Date = Target.getTime();

	//Find their difference, and convert that into seconds.
	var Time_Left = Math.round((Target_Date - Todays_Date) / 1000);
	if (Time_Left < 0) Time_Left = 0;

	switch(format) {
		case 1:
			//More detailed.
			var days = Math.floor(Time_Left / 86400); // 60 * 60 * 24
			Time_Left %= 86400;
			var hours = Math.floor(Time_Left / 3600); // 60 * 60
			Time_Left %= 3600;
			var minutes = Math.floor(Time_Left / 60);
			Time_Left %= 60;
			var seconds = Time_Left;

			//ps is short for plural suffix.
			var dps = 's'; 
			var hps = 's'; 
			var mps = 's'; 
			var sps = 's';
			
			if(days == 1) dps ='';
			if(hours == 1) hps ='';
			if(minutes == 1) mps ='';
			if(seconds == 1) sps ='';

			elemCountDown.innerHTML = days + ' day' + dps + ' <br>';
			elemCountDown.innerHTML += hours + ' hour' + hps + ' <br>';
			elemCountDown.innerHTML += minutes + ' minute' + mps + ' <br>';
			elemCountDown.innerHTML += seconds + ' second' + sps;
			break;
		default:
			elemCountDown.innerHTML = Time_Left + ' seconds';
	}

	setTimeout('countdown(' + year + ',' + month + ',' + day + ',' + hour + ',' + minute + ',' + format + ');', 1000);
}

//This function assists in obscuring email addresses
function mailTo(obj) {
	//alert('mailto:'+eval(obj.getAttribute('id')));
	obj.setAttribute('href', 'mailto:'+eval(obj.getAttribute('id')));
}

function js_mail(obj,Emails) {
	var mail_link = Emails[0];
		for (var email = 1; email < Emails.length; email++)
			if (Emails[email] != null && Emails[email] != '') mail_link = mail_link + Emails[email];

	obj.setAttribute('href', 'mailto:' + mail_link);
}

function antiContextMenuHook() {
	// Note: Opera is not hookable.
	var showAlert = function() { alert('All images are protected by Copyright. Do not use without permission.'); }
	var mdClick = function(e) {
		if (!document.all) { if (e.button == 2 || e.button == 3) showAlert(); }
		else if (event && event.button == 2) showAlert();
	}
	var cmClick = function(e) {
		if (navigator.userAgent.toLowerCase().indexOf('khtml') > -1) {
			// Safari, Konquerer
			if (e.preventDefault) e.preventDefault(); showAlert();
		}
		if (e.stopPropagation) e.stopPropagation(); // Mozilla Firefox 2.0
		return false; // IE 6.0 and 7.0
	}
	document.onmousedown = mdClick;
	document.oncontextmenu = cmClick;
}

// form validation functions
function RegExValidate(expression, value, param) {
	var re = new RegExp(expression, param);
	if (value.match(re))return true;
	else return false;
}


function emailValidate(value) {
    return RegExValidate('^[A-Z0-9._%-]+@[A-Z0-9.-]+\.[A-Z]{2,6}$', value, 'i');
}

function dateValidator() {
	this.firstValidDate = new Date('01/01/1753');
	this.lastValidDate = new Date('01/01/3000');
	this.strStartDateID = 'Start Date';
	this.strEndDateID = 'End Date';
	this.strStartTimeID = 'Start Time';
	this.strEndTimeID = 'End Time';
	this.ysnRequireStartDateIfEndSpecified = false;
	this.ysnStartDateRequired = false;
	this.ysnEndDateRequired = false;
	this.ysnStartTimeRequired = false;
	this.ysnEndTimeRequired = false;
	this.ysnAllowEqualDates = false;
	this.ysnCent = false; //Allow only four digit years
	var dtiEndDate;
	var dtiStartDate;

	this.setStartDate = function(date) {
	  dtiStartDate = this.cleanDate(date);
	}

	this.setEndDate = function(date) {
	  dtiEndDate = this.cleanDate(date);
	}

	this.cleanDate = function(date) {
	    if (date) {
	        if(RegExValidate('^([0-9\-\\\/]*?)([0-9]{2,4})$',date,'i')) {
	            var year = RegExp.$2;
		        if (year.length == 2) {
		            if (year >= 50) date = RegExp.$1+"19"+year;
		            else date = RegExp.$1+"20"+year;
		        }
		        date = date.replace('\-','/', 'g');
		    }
		}
		return date;
	}

	this.dateValidate = function(dtiDate, ysnRequired, strID) {
	    if (!ysnRequired && dtiDate == '') return true;
	    else if (ysnRequired && dtiDate == '') {
	        if (strID) this.error = strID +' is required';
	        else this.error = ' is required';
	        this.errorNumber = 1;
	        return false;
	    }
		else if (RegExValidate('^(1[0-2]|0?[1-9])(\/|\-)(0?[1-9]|[1-2][0-9]|3[0-1])\\2([0-9]{4}|[0-9]{2})$',dtiDate,'i')) {
			var month = RegExp.$1;
			var day = RegExp.$3;
			var year = RegExp.$4;

		    if (year.length ==2 && this.ysnCent == true) {
		        if (strID) this.error=strID+' requires a four digit year';
	            else this.error='Please use a four digit year';
		        return false;
		    }
			if (year.length==4 && (year>3000 || year<1753)) {
				this.error=dtiDate+'\nis outside of the date range.';
				this.errorNumber=2;
				return false;
			}
			if (day == 31 && (month == 4 || month == 6 || month == 9 || month == 11)) {
				this.error = 'This month doesn\'t have 31 days';
				this.errorNumber = 3;
				return false;
			}
			if (day >= 30 && month == 2) {
				this.error = 'February doesn\'t have '+day+' days';
				this.errorNumber = 4;
				return false;
			}
			if (month == 2 && day == 29 && !(year % 4 == 0 && (year % 100 != 0 || year % 400 == 0))) {
				this.error = 'This is not a leap year\nFebruary doesn\'t have 29 days.';
				this.errorNumber = 5;
				return false;
			}
			return true;
		}
		else  {
			if (strID) this.error = strID+' is not a valid date format.\nPlease use mm/dd/yyyy.';
	        else this.error = dtiDate+'\n is an invalid date format.\nPlease use mm/dd/yyyy.';
			this.errorNumber = 6;
			return false;
		}
		return false;
	}

	this.dateOrderValidate = function() {
		if(this.dateValidate(dtiStartDate,this.ysnStartDateRequired,this.strStartDateID) && this.dateValidate(dtiEndDate, this.ysnEndDateRequired,this.strEndDateID)) {
			if (this.ysnRequireStartDateIfEndSpecified && !dtiStartDate && dtiEndDate) {
				this.error = 'A start date must be specified if an end date was entered.'
				this.errorNumber = 9; return false;
			}
		    if (!dtiStartDate || !dtiEndDate) return true;
		    else {
		        var StartDate = new Date(dtiStartDate);
		        var EndDate = new Date(dtiEndDate);
		    }
			if (StartDate.getTime() < EndDate.getTime()) return true;
			else if (StartDate.getTime() == EndDate.getTime() && this.ysnAllowEqualDates == true) {
			    this.ysnDatesAreEqual = true;
			    return true;
			}
			else {
			    this.error = 'The end date must be after the start date.';
			    this.errorNumber = 7; return false;
			}
		}
		else return false;
	}

	this.format = function(format, date) {
		if (!date) var date = new Date();
		var day = date.getDate();
		var month = date.getMonth() + 1;
		var year = date.getFullYear();
		return format.replace(/dd/g, day).replace(/mm/g, month).replace(/y{1,4}/g, year)
	}

	this.timeValidate = function(ditTime, ysnRequired, strID)
    {
        if (!ysnRequired && ditTime == '') return true;
	    else if (ysnRequired && ditTime == '')
	    {
	        if (strID) this.error = strID+' is required';
	        else this.error = 'Time is required';
	        this.errorNumber = 1;
	        return false;
	    }
        else if (RegExValidate('^(1[0-2]|0?[1-9]):([0-5]?[0-9])(:([0-5][0-9]))?$',ditTime,'i')) return true;
        else
        {
            if (strID) this.error = strID+' is not valid.';
            else this.error = ' is not valid.';
            this.errorNumber = 8;
            return false;
        }
        return false;
    }

    this.timeOrderValidate = function ()
    {
        if(!this.ysnAllowTimeOnly && ((!dtiStartDate && this.dtiStartTime) || (!dtiEndDate && this.dtiEndTime)))
        {
            this.error = 'You only submited a time.\nPlease provide a day as well.';
            this.errorNumber = 10;
            return false;
        }
        if(this.timeValidate(this.dtiStartTime, this.ysnStartTimeRequired, this.strStartTimeID) && this.timeValidate(this.dtiEndTime, this.ysnEndTimeRequired, this.strEndTimeID))
		{
		    if (!this.ysnDatesAreEqual) return true;

		    var dtiStartTime = this.convertTo24Hour(this.dtiStartTime, this.strStartAMPM, dtiStartDate);
		    var dtiEndTime = this.convertTo24Hour(this.dtiEndTime, this.strEndAMPM, dtiEndDate);

		    if (dtiStartTime.getTime() < dtiEndTime.getTime())return true;
            else if (dtiStartTime.getTime() == dtiEndTime.getTime() && this.ysnAllowEqualTimes == true)
			{
			    this.ysnTimesAreEqual = true;
			    return true;
			}
			else
			{
			    this.error = 'The End Time must be after the Start Time if the Start and End Dates are the same.'
			    this.errorNumber = 9;
			    return false;
			}
		    return false;
        }
        return false;
    }

    this.convertTo24Hour=function(time, AMPM, date)
    {
        if (!date) date = "1/1/70"
        time = new Date(date+" "+time);
		if (AMPM == 'AM' && time.getHours() == 12) time.setHours(0);
		else if(AMPM == 'PM' && time.getHours() != 12) time.setHours(time.getHours()+12);
		return time;
    }
}

function inputEmailValidate(obj,required) {
    if (required == null || required == false)
    {
        if (obj.value == '' || emailValidate(obj.value) == true) return true;
        else return false;
    }
    else
    {
        if (obj.value != '' && emailValidate(obj.value) == true) return true;
        else return false;
    }
}


function inputAlert(call, obj, required, errorMessage) {
	call = eval('input'+call+'Validate');
	if (call(obj, required) == false) {
		if (errorMessage == null) errorMessage = 'Please enter a single valid email address without any extra body, subject, etc. information (ie user@domain.com).';
		obj.setAttribute('autocomplete','off');
		obj.focus();
		obj.setAttribute('autocomplete','on');
		alert(errorMessage);
		return false
	} 
	else 
		return true;
}
//End Form Validation functions

//Begin AJAX functions
function makeErrorRequest(url, status) {
	alert("There was an error processing your request (Status: " + status + "). Please try again. If this problem persists, please contact CivicPlus support.");

	var http_error_request = false;
	var origin = location.pathname;

	if (window.XMLHttpRequest) { // Mozilla, Safari, IE7
		http_error_request = new XMLHttpRequest();
		if (http_error_request.overrideMimeType)
			http_error_request.overrideMimeType("text/html");
	} else if (window.ActiveXObject) { // IE6
		try {
			http_error_request = new ActiveXObject("Msxml2.XMLHTTP.6.0");
		} catch (e) {
			try { 
				http_error_request = new ActiveXObject("Msxml2.XMLHTTP"); // Version 3.0
			} catch (e) {}
		}
	}

	http_error_request.onreadystatechange = function() {}
	http_error_request.open("GET", "/AJAX-error.asp?url=" + escape(url) + "&status="+ status + "&origin=" + escape(origin), true);
	http_error_request.send(null);
}

function makeHttpRequest(url, callback_function, return_xml) {
	var http_request = false;

    if (window.XMLHttpRequest) { // Mozilla, Safari, IE7
        http_request = new XMLHttpRequest();
        if (http_request.overrideMimeType) {
            http_request.overrideMimeType("text/html");
        }
    } else if (window.ActiveXObject) { // IE6
        try {
            http_request = new ActiveXObject("Msxml2.XMLHTTP.6.0");
        } catch (e) {
            try { 
                http_request = new ActiveXObject("MSxml2.XMLHTTP"); // Version 3
            } catch (e) {}
        }
    }

	if (!http_request) { 
		alert("Unfortunately, your browser doesn't support this feature.");
		return false;
	}

	http_request.onreadystatechange = function() {
		if (http_request.readyState == 4) {
			--ajax_call_counter;

			try {
				if (http_request.status == 200) {
					if (return_xml)
						eval(callback_function + ', http_request.responseXML)');
					else {
						if (http_request.responseText.search(/<form action='error.asp' method=post>/i) < 0)
							eval(callback_function + ', http_request.responseText)');
						else
							makeErrorRequest(url, http_request.status);
					}
				}
				else if (http_request.status)
					makeErrorRequest(url, http_request.status);
			} catch (e) {
				var USER_EXPLAIN_ERR_EN = 
					'An error occured while downloading additional page content.\nIf you continue to see this message, you are encouraged to contact CivicPlus support.\n\nTechnical Details:\n' + e.name + ' - ';

				// IE 6 & 7: No Line Number, No Filename
				if (document.all && !window.opera) { 
					alert(USER_EXPLAIN_ERR_EN + e.description + ' (line unavailable, code: ' + e.number + ')' + '\n\nJ-Script Callback:\n' + callback_function + ', <responseData>);');
				} 
				// Opera and Firefox 1.5+: Line Number + Filename
				else {
					alert(USER_EXPLAIN_ERR_EN + e.message + '\n' + e.fileName + ', line ' + e.lineNumber + '\n\nJavaScript Callback:\n' + callback_function + ', <responseData>);');
				}
			}

			http_request = null;
		}
	}

	http_request.open("GET", url, true);
	http_request.send(null);
}
// Invoked on window.onunload for pages using synchronous AHAH.
// Catches switches to different pages and window closes.
// -=-=-=-=-
// Note: It is synchronous instead of asynchronous to ensure 
// the operation completes before a close. This is SHAH.
//
function destroyAHAH() {
	var http_request;

	if (window.XMLHttpRequest) { // Mozilla, Safari, IE7
		http_request = new XMLHttpRequest();
		if (http_request.overrideMimeType) {
			http_request.overrideMimeType("text/html");
		}
	} else if (window.ActiveXObject) { // IE6
		try {
			http_request = new ActiveXObject("MSXML2.XMLHTTP.6.0");
		} catch (e) {
			try { 
				http_request = new ActiveXObject("MSXML2.XMLHTTP"); // Version 3
			} catch (e) {}
		}
	}

	if (!http_request) return;
	http_request.open("GET", 'http://'+window.location.host+'/AJAX-nmenuLoader.asp?clearCache=1', false);
	http_request.send(null);
	//alert(http_request.status + ': if 200, the session cache object was term\'d where needed be.');
}
//End AJAX functions

//  
//  slideShow class
//  vars:
//  slideShowId						constructor param for the id of the image that will have the Slide Show 
//  slideShowLink					constructor param for the id of the link that will be around the image that has Slide Show, use '' for no link
//  slideShowSpeed					optional constructor param for the speed of the slide show, default = 5000
//  filterName						optional constructor param for the IE filter, default = blendTrans
//  filterAttr1						optional constructor param for the IE filter, default = duration=3
//  filterAttr2						optional constructor param for the IE filter
//  filterAttr3						optional constructor param for the IE filter
//  j								counter for the object
//  picArr							array of pictures
//  altArr							array of alt text
//  linkArr							array of links
//  methods:
//  addImage(n, img, alt, link)		add an image with alt text and a link, n specifies which postion in the arrays
//  runSlideShow()					continually calls nextSlide to run the Slide Show
//  nextSlide()						applies the transition and advances the Slide Show image 1 spot in the arrays
//  
function slideShow(slideShowId, slideShowLink, slideShowSpeed, filterName, filterAttr1, filterAttr2, filterAttr3) {
	this.slideShowId = document.getElementById(slideShowId);
	this.slideShowLink = slideShowLink;
	this.j = 1;
	if (slideShowSpeed == null || slideShowSpeed == '')
		this.slideShowSpeed = 4000;
	else
		this.slideShowSpeed = slideShowSpeed * 1000;
	if (filterAttr1 == null || filterAttr1 == '')
		filterAttr1 = 2;
	if (filterName == null || filterName == '' || filterName.toLowerCase() == 'blendtrans')
		this.filterName = 'BlendTrans(duration=' + filterAttr1;
	else if (filterName.toLowerCase() != 'none')
		this.filterName = 'progid:DXImageTransform.Microsoft.' + filterName + ', duration=' + filterAttr1;
	if (filterAttr2 != null && filterAttr2 != '')
		this.filterName = this.filterName + ',' + filterAttr2;
	if (filterAttr3 != null && filterAttr3 != '')
		this.filterName = this.filterName + ',' + filterAttr3;
	this.filterName = this.filterName + ')';
	
	this.picArr = new Array();
	this.altArr = new Array();
	this.linkArr = new Array();
	
	this.addImage = function(n, img, alt, link) {
		this.picArr[n] = new Image();
		this.picArr[n].src = img;
		this.altArr[n] = alt;
		this.linkArr[n] = link;
	}
	
	this.runSlideShow = function() {
		var self = this;						//  reference to get around context loss of this during setTimeout()
		this.timeoutId = setTimeout(function() { self.nextSlide(); self.runSlideShow(); }, this.slideShowSpeed);
	}
	
	this.nextSlide = function() {
		if (document.all && this.slideShowId.filters && filterName.toLowerCase() != 'none') {
			this.slideShowId.style.filter = this.filterName;
			this.slideShowId.filters.item(0).apply();
		}
		this.slideShowId.setAttribute('src', this.picArr[this.j].src);
		this.slideShowId.setAttribute('alt', this.altArr[this.j]);
		if (document.getElementById(this.slideShowLink))
			document.getElementById(this.slideShowLink).setAttribute('href', this.linkArr[this.j]);
		if (document.all && this.slideShowId.filters && filterName.toLowerCase() != 'none')
			this.slideShowId.filters.item(0).play();
		
		this.j++;
		if (this.j >= this.picArr.length)
			this.j = 0;
	}
}

