﻿Ajax.SelectUpdater = Class.create(Ajax.Request, {
	initialize: function($super, element, newElement, url, options) {

		options = Object.clone(options);
		var onComplete = options.onComplete;
		options.onComplete = (function(response, json) {
			element = $(element);
			var id = element.id;
			var name = element.name;
			element.replace(response.responseText);
			newElement = $(newElement);
			newElement.id = id;
			newElement.name = name;

			if (Object.isFunction(onComplete)) {
				onComplete(response, json);
			}
		}).bind(this);

		$super(url, options);
	}
});

Object.extend(String.prototype, {
	isBlank: function() {
		return /^ *$/.test(this);
	},

	trim: function() {
		return this.replace(/(^ +| +$)/g, "");
	},

	isNumeric: function() {
		//blank strings are always considered valid
		return this == "" || /^-?([0-9]+(\.[0-9]+){0,1}|\.[0-9]+)$/.test(this);
	},

	isEmail: function() {
		//blank strings are always considered valid
		return this == "" || /^([a-zA-Z0-9_\.\-])+\@([a-zA-Z0-9.\-])+(\.[a-zA-Z0-9]{2,4})+$/.test(this);
	},

	//used to encode a string for use in a regular expression.
	//this is useful for the string.replace method, since the first
	//argument normally takes a RegExp object.
	regexEncode: function() {
		return this.replace(/([.*+?^${}()|[\]\/\\])/g, "\\$1");
	},

	htmlEncode: function() {
		return this.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;");
	},

	createDate: function() {
		var dateParts = this.split("/");
		var month = parseInt(dateParts[0], 10);
		var day = parseInt(dateParts[1], 10);
		var year = parseInt(dateParts[2], 10);

		return new Date(year, month - 1, day, 0, 0, 0, 1);
	},

	isDate: function() {
		//blank strings are always considered valid
		if (this == "") {
			return true;
		}

		//mm/dd/yyyy
		var pattern = /^(1[0-2]|0?[1-9])\/(0?[1-9]|[12][0-9]|3[01])\/(\d\d\d\d)$/;

		if (!pattern.test(this)) {
			return false;
		}

		var dateParts = this.split("/");
		var month = parseInt(dateParts[0], 10);
		var day = parseInt(dateParts[1], 10);
		var year = parseInt(dateParts[2], 10);

		if (!IsDateValid(month, day, year)) {
			return false;
		}

		return true;
	}
});

Object.extend(Date.prototype, {
	daysBetween: function(dateToCompare) {
		var difference =
    	    Date.UTC(dateToCompare.getFullYear(), dateToCompare.getMonth(), dateToCompare.getDate(), 0, 0, 0)
	      - Date.UTC(this.getFullYear(), this.getMonth(), this.getDate(), 0, 0, 0);

		return Math.floor(Math.abs(difference / 1000 / 60 / 60 / 24));
	},

	toShortDateString: function() {
		return (this.getMonth() + 1).toString() + "/" + this.getDate().toString() + "/" + this.getFullYear().toString();
	},

	isWeekend: function() {
		return this.getDay() == 0 || this.getDay() == 6;
	},

	add: function(value, unit) {

		unit = unit.toLowerCase();

		switch (unit) {
			case "y":
				return new Date(this.getFullYear() + value, this.getMonth(), this.getDate(), this.getHours(), this.getMinutes(), this.getSeconds());
			case "m":
				return new Date(this.getFullYear(), this.getMonth() + value, this.getDate(), this.getHours(), this.getMinutes(), this.getSeconds());
			case "d":
				return new Date(this.getFullYear(), this.getMonth(), this.getDate() + value, this.getHours(), this.getMinutes(), this.getSeconds());
			case "h":
				return new Date(this.getFullYear(), this.getMonth(), this.getDate(), this.getHours() + value, this.getMinutes(), this.getSeconds());
			case "n":
				return new Date(this.getFullYear(), this.getMonth(), this.getDate(), this.getHours(), this.getMinutes() + value, this.getSeconds());
			case "s":
				return new Date(this.getFullYear(), this.getMonth(), this.getDate(), this.getHours(), this.getMinutes(), this.getSeconds() + value);
			default:
				return null;
		}
	}
});

function IsDateValid(month, day, year) {
	if (month.toString().isBlank()
		|| day.toString().isBlank()
		|| year.toString().isBlank()
		|| !month.toString().isNumeric()
		|| !day.toString().isNumeric()
		|| !year.toString().isNumeric()
		|| month.toString().indexOf(".") != -1
		|| day.toString().indexOf(".") != -1
		|| year.toString().indexOf(".") != -1
		|| year.toString().length != 4) {
		return false;
	}

	var date = new Date(year, month - 1, day, 0, 0, 0, 1);
	return date.getMonth() + 1 == month && date.getDate() == day && date.getFullYear() == year;
}

Object.extend(Number.prototype, {
	numberFormat: function() {
		var parts = this.toString().split(".");
		var number = "";

		for (var i = parts[0].length - 1; i >= 0; i--) {
			if ((parts[0].length - i) % 3 == 0 && i > 0) {
				number = "," + parts[0].charAt(i) + number;
			}
			else {
				number = parts[0].charAt(i) + number;
			}
		}

		if (parts.length > 1) {
			number += "." + parts[1];
		}

		return number;
	}
});

//binds a date picker to a form element
//requires /Style/fastDatePicker.css and /JavaScript/fastDatePicker.js
function bindDatePicker(elementName) {

	var element = $(elementName);
	var a = Element.extend(document.createElement("a"));
	a.href = "#";
	a.update("<img src=\"/Images/calendar.png\" align=\"bottom\" hspace=\"5\" />");
	a.title = "Select Date";

	Event.observe(a, "click", function(evt) {
		var existingCalendar = $(element.id + "_cal");

		//if we already have the calendar showing, hide it
		if (existingCalendar) {
			existingCalendar.remove();
			return;
		}

		//create the div to hold the calendar
		var container = Element.extend(document.createElement("div"));
		var position = Position.cumulativeOffset(element);
		var dimensions = element.getDimensions();

		container.id = element.id + "_cal";

		var imageButton = evt.element();
		var imageButtonPosition = imageButton.positionedOffset();

		//set up the position of the div
		container.setStyle({
			position: "absolute",
			backgroundColor: "#FFFFFF",
			left: imageButtonPosition[0] + imageButton.width + 10 + "px",
			top: (imageButtonPosition[1]) + imageButton.height + 10 + "px"
		});

/*
		//set up the position of the div
		container.setStyle({
			position: "absolute",
			backgroundColor: "#FFFFFF",
			left: position[0] + 90 + "px",
			top: (position[1] + dimensions.height - 90) + "px"
		});
*/
		//create the date picker
		var picker = new FastDatePicker();

		//wire it up so that when a date is picked, the element we're binding 
		//to gets the date in mm/dd/yyyy format
		picker.handleSelection = function dr_SelectDate(container, picker) {
			this.value = picker.date.toShortDateString();
			container.remove();
		} .bind(element, container, picker);

		//don't put a restriction on the dates they can pick
		picker.firstSelectableDate = null;

		//if the field already has a date in it, let's tell the date picker
		//to default to that date
		if (!element.value.isBlank() && element.value.isDate()) {
			picker.date = new Date(Date.parse(element.value));
			picker.selectedDate = new Date(picker.date);
		}

		//add the picker and container to the document
		container.appendChild(picker.calendar());
		element.up().appendChild(container);

		Event.stop(evt);
	});

	//add the a tag after the element
	if (!element.nextSibling) {
		element.up().appendChild(a);
	}
	else {
		element.up().insertBefore(a, element.nextSibling);
	}
};

//wrappers for pretty dialogs
function alertDialog(text, okCallback) {
	Dialog.alert(text, {
		onOk: okCallback || false,
		okLabel: "OK",
		windowParameters: {
			className: "alphacube",
			effectOptions: {
				duration: .25
			}
		}
	});
};

function confirmDialog(text, okCallback, cancelCallback, okLabel, cancelLabel, windowParameters) {
	Dialog.confirm(text, {
		onOk: okCallback,
		okLabel: okLabel || "OK",
		cancelLabel: cancelLabel || "Cancel",
		onCancel: cancelCallback,
		windowParameters: Object.extend({
			className: "alphacube",
			effectOptions: {
				duration: .25
			}
		}, windowParameters || {})
	});
};

function contentDialog(element, options) {
	element = $(element);

	options = Object.extend({
		className: "alphacube",
		effectOptions: {
			duration: .25
		},
		destroyOnClose: true,
		modal: false
	}, options || {});

	var w = new Window("win", options);
	w.setContent(element, true, true);

	if (options.width) {
		w.setSize(options.width, w.getSize().height);
	}

	if (options.height) {
		w.setSize(w.getSize().width, options.height);
	}

	w.toFront();
	w.showCenter(options.modal);

	return w;
};

//use a class name of Rounded on any div to apply
//rounded corners and backgrounds when this method is called
function applyRounding() {

	document.getElementsByClassName("Rounded").each(function(element) {
		var top = Element.extend(document.createElement("div")).addClassName("RoundedTop");
		var content = Element.extend(document.createElement("div")).addClassName("RoundedContent");
		var bottom = Element.extend(document.createElement("div")).addClassName("RoundedBottom").update("<div></div>");

		content.appendChild(top);
		$A(element.childNodes).each(function(child) { content.appendChild(child); });

		element.appendChild(content);
		element.appendChild(bottom);
	});
};

//this is needed, but empty, for everything but IE6 - see ie6png.js
var FixPng;
