/*  Copyright Mihai Bazon, 2002, 2003  |  http://dynarch.com/mishoo/
 * ---------------------------------------------------------------------------
 *
 * The DHTML Calendar
 *
 * Details and latest version at:
 * http://dynarch.com/mishoo/calendar.epl
 *
 * This script is distributed under the GNU Lesser General Public License.
 * Read the entire license text here: http://www.gnu.org/licenses/lgpl.html
 *
 * This file defines helper functions for setting up the calendar.  They are
 * intended to help non-programmers get a working calendar on their site
 * quickly.  This script should not be seen as part of the calendar.  It just
 * shows you what one can do with the calendar, while in the same time
 * providing a quick and simple method for setting it up.  If you need
 * exhaustive customization of the calendar creation process feel free to
 * modify this code to suit your needs (this is recommended and much better
 * than modifying calendar.js itself).
 */

// $Id: calendar-setup.js,v 1.25 2005/03/07 09:51:33 mishoo Exp $

/**
 *  This function "patches" an input field (or other element) to use a calendar
 *  widget for date selection.
 *
 *  The "params" is a single object that can have the following properties:
 *
 *    prop. name   | description
 *  -------------------------------------------------------------------------------------------------
 *   inputField    | the ID of an input field to store the date
 *   inputDisplayField  | the ID of an input field to display the date
 *   displayArea   | the ID of a DIV or other element to show the date
 *   button        | ID of a button or other element that will trigger the calendar
 *   eventName     | event that will trigger the calendar, without the "on" prefix (default: "click")
 *   ifFormat      | date format that will be stored in the input field
 *   daFormat      | the date format that will be used to display the date in displayArea
 *   singleClick   | (true/false) wether the calendar is in single click mode or not (default: true)
 *   firstDay      | numeric: 0 to 6.  "0" means display Sunday first, "1" means display Monday first, etc.
 *   align         | alignment (default: "Br"); if you don't know what's this see the calendar documentation
 *   range         | array with 2 elements.  Default: [1900, 2999] -- the range of years available
 *   weekNumbers   | (true/false) if it's true (default) the calendar will display week numbers
 *   flat          | null or element ID; if not null the calendar will be a flat calendar having the parent with the given ID
 *   flatCallback  | function that receives a JS Date object and returns an URL to point the browser to (for flat calendar)
 *   disableFunc   | function that receives a JS Date object and should return true if that date has to be disabled in the calendar
 *   onSelect      | function that gets called when a date is selected.  You don't _have_ to supply this (the default is generally okay)
 *   onClose       | function that gets called when the calendar is closed.  [default]
 *   onUpdate      | function that gets called after the date is updated in the input field.  Receives a reference to the calendar.
 *   date          | the date that the calendar will be initially displayed to
 *   showsTime     | default: false; if true the calendar will include a time selector
 *   timeFormat    | the time format; can be "12" or "24", default is "12"
 *   electric      | if true (default) then given fields/date areas are updated for each move; otherwise they're updated only on close
 *   step          | configures the step of the years in drop-down boxes; default: 2
 *   position      | configures the calendar absolute position; default: null
 *   cache         | if "true" (but default: "false") it will reuse the same calendar object, where possible
 *   showOthers    | if "true" (but default: "false") it will show days from other months too
 *
 *  None of them is required, they all have default values.  However, if you
 *  pass none of "inputField", "displayArea" or "button" you'll get a warning
 *  saying "nothing to setup".
 */
Calendar.setupLocalization = function (localeArray)
{
    // ** I18N

    // Calendar EN language
    // Author: Mihai Bazon, <mihai_bazon@yahoo.com>
    // Encoding: any
    // Distributed under the same terms as the calendar itself.

    // For translators: please use UTF-8 if possible.  We strongly believe that
    // Unicode is the answer to a real internationalized world.  Also please
    // include your contact information in the header, as can be seen above.

    // full day names
    
    Calendar._DN = new Array
    (localeArray["Sunday"],
     localeArray["Monday"],
     localeArray["Tuesday"],
     localeArray["Wednesday"],
     localeArray["Thursday"],
     localeArray["Friday"],
     localeArray["Saturday"],
     localeArray["Sunday"]);

    // Please note that the following array of short day names (and the same goes
    // for short month names, _SMN) isn't absolutely necessary.  We give it here
    // for exemplification on how one can customize the short day names, but if
    // they are simply the first N letters of the full name you can simply say:
    //
    //   Calendar._SDN_len = N; // short day name length
    //   Calendar._SMN_len = N; // short month name length
    //
    // If N = 3 then this is not needed either since we assume a value of 3 if not
    // present, to be compatible with translation files that were written before
    // this feature.

    // short day names
    Calendar._SDN = new Array
    (localeArray["Sun"],
     localeArray["Mon"],
     localeArray["Tue"],
     localeArray["Wed"],
     localeArray["Thu"],
     localeArray["Fri"],
     localeArray["Sat"],
     localeArray["Sun"]);

    // First day of the week. "0" means display Sunday first, "1" means display
    // Monday first, etc.
    Calendar._FD = 0;

    // full month names
    Calendar._MN = new Array
    (localeArray["January"],
     localeArray["February"],
     localeArray["March"],
     localeArray["April"],
     localeArray["May"],
     localeArray["June"],
     localeArray["July"],
     localeArray["August"],
     localeArray["September"],
     localeArray["October"],
     localeArray["November"],
     localeArray["December"]);

    // short month names
    Calendar._SMN = new Array
    (localeArray["Jan"],
     localeArray["Feb"],
     localeArray["Mar"],
     localeArray["Apr"],
     localeArray["May"],
     localeArray["Jun"],
     localeArray["Jul"],
     localeArray["Aug"],
     localeArray["Sep"],
     localeArray["Oct"],
     localeArray["Nov"],
     localeArray["Dec"]);

    // tooltips
    Calendar._TT = {};
    Calendar._TT["INFO"] = localeArray["INFO"];
    
    Calendar._TT["ABOUT"] = localeArray["ABOUT"];
    Calendar._TT["ABOUT_TIME"] = localeArray["ABOUT_TIME"];
    
    /*Calendar._TT["ABOUT"] =
    "DHTML Date/Time Selector\n" +
    "(c) dynarch.com 2002-2005 / Author: Mihai Bazon\n" + // don't translate this this ;-)
    "For latest version visit: http://www.dynarch.com/projects/calendar/\n" +
    "Distributed under GNU LGPL.  See http://gnu.org/licenses/lgpl.html for details." +
    "\n\n" +
    "Date selection:\n" +
    "- Use the \xab, \xbb buttons to select year\n" +
    "- Use the " + String.fromCharCode(0x2039) + ", " + String.fromCharCode(0x203a) + " buttons to select month\n" +
    "- Hold mouse button on any of the above buttons for faster selection.";
    Calendar._TT["ABOUT_TIME"] = "\n\n" +
    "Time selection:\n" +
    "- Click on any of the time parts to increase it\n" +
    "- or Shift-click to decrease it\n" +
    "- or click and drag for faster selection.";*/

    Calendar._TT["PREV_YEAR"] = localeArray["PREV_YEAR"];
    Calendar._TT["PREV_MONTH"] = localeArray["PREV_MONTH"];
    Calendar._TT["GO_TODAY"] = localeArray["GO_TODAY"];
    Calendar._TT["NEXT_MONTH"] = localeArray["NEXT_MONTH"];
    Calendar._TT["NEXT_YEAR"] = localeArray["NEXT_YEAR"];
    Calendar._TT["SEL_DATE"] = localeArray["SEL_DATE"];
    Calendar._TT["DRAG_TO_MOVE"] = localeArray["DRAG_TO_MOVE"];
    Calendar._TT["PART_TODAY"] = localeArray["PART_TODAY"];

    // the following is to inform that "%s" is to be the first day of week
    // %s will be replaced with the day name.
    Calendar._TT["DAY_FIRST"] = localeArray["DAY_FIRST"];

    // This may be locale-dependent.  It specifies the week-end days, as an array
    // of comma-separated numbers.  The numbers are from 0 to 6: 0 means Sunday, 1
    // means Monday, etc.
    Calendar._TT["WEEKEND"] = "0,6";

    Calendar._TT["CLOSE"] = localeArray["CLOSE"];
    Calendar._TT["TODAY"] = localeArray["TODAY"];
    Calendar._TT["TIME_PART"] = localeArray["TIME_PART"];

    // date formats
    Calendar._TT["DEF_DATE_FORMAT"] = "%Y-%m-%d";
    Calendar._TT["TT_DATE_FORMAT"] = "%a, %b %e";

    Calendar._TT["WK"] = localeArray["WK"];
    Calendar._TT["TIME"] = localeArray["TIME"];
};
Calendar.setup = function (params) {
	function param_default(pname, def) { if (typeof params[pname] == "undefined") { params[pname] = def; } };

	param_default("inputField",     null);
	param_default("inputDisplayField", null);
	param_default("displayArea",    null);
	param_default("button",         null);
	param_default("eventName",      "click");
	param_default("ifFormat",       "%Y/%m/%d");
	param_default("daFormat",       "%Y/%m/%d");
	param_default("singleClick",    true);
	param_default("disableFunc",    null);
	param_default("dateStatusFunc", params["disableFunc"]);	// takes precedence if both are defined
	param_default("dateText",       null);
	param_default("firstDay",       null);
	param_default("align",          "Br");
	param_default("range",          [1900, 2999]);
	param_default("weekNumbers",    true);
	param_default("flat",           null);
	param_default("flatCallback",   null);
	param_default("onSelect",       null);
	param_default("onClose",        null);
	param_default("onUpdate",       null);
	param_default("date",           null);
	param_default("showsTime",      false);
	param_default("timeFormat",     "24");
	param_default("electric",       true);
	param_default("step",           2);
	param_default("position",       null);
	param_default("cache",          false);
	param_default("showOthers",     false);
	param_default("multiple",       null);

	var tmp = ["inputField", "displayArea", "button"];
	for (var i in tmp) {
		if (typeof params[tmp[i]] == "string") {
			params[tmp[i]] = document.getElementById(params[tmp[i]]);
		}
	}
	if (!(params.flat || params.multiple || params.inputField || params.displayArea || params.button)) {
		alert("Calendar.setup:\n  Nothing to setup (no fields found).  Please check your code");
		return false;
	}

	function onSelect(cal) {
		var p = cal.params;
		var update = (cal.dateClicked || p.electric);
		//-- Commented out this portion and added it to the lower portion. There's no need to update the text
		//-- as we are navigatng through the calendar... dwhitten 5/9/08
		/*if (update && p.inputField) {
		    p.inputField.value = cal.date.print(p.ifFormat);
		    if (typeof p.inputField.onchange == "function")
				p.inputField.onchange();
		}
		if (update && p.displayArea)
			p.displayArea.innerHTML = cal.date.print(p.daFormat);
		if (update && typeof p.onUpdate == "function")
			p.onUpdate(cal);
		if (update && p.flat) {
			if (typeof p.flatCallback == "function")
				p.flatCallback(cal);
		}*/
		if (update && p.singleClick && cal.dateClicked)
		{
		    //-- Just update the text field only if we actually select a date, and not when navigating
		    //-- through the months and years... dwhitten 5/9/08
		    //------------ Begin Added Section ---------------------------------
		if (update && p.inputField) {
		//FPW-8006 - disable add to cart if selected date on calendar has changed
	        if(p.inputField.value!=cal.date.print(p.ifFormat)) 
	        {
			    p.inputField.value = cal.date.print(p.ifFormat);
	            if (typeof(DisableAddFromVersionedForm) == "function")
					DisableAddFromVersionedForm();
				else if (typeof(DisableAdd) == "function")
					DisableAdd();
	        }
			if (typeof p.inputField.onchange == "function")
				p.inputField.onchange();
		}
		if (update && p.displayArea) {
		//FPW-8006 - disable add to cart if selected date on calendar has changed
	        if(p.displayArea.innerHTML!=cal.date.print(p.daFormat)) 
	        {
                if (typeof(DisableAddFromVersionedForm) == "function")
					DisableAddFromVersionedForm();
				else if (typeof(DisableAdd) == "function")
					DisableAdd();
			    p.displayArea.innerHTML = cal.date.print(p.daFormat);
	        }
	    }
		if (update && typeof p.onUpdate == "function")
			p.onUpdate(cal);
		if (update && p.flat) {
			if (typeof p.flatCallback == "function")
				p.flatCallback(cal);
		}
		    //------------ End Added Section -----------------------------------
			cal.callCloseHandler();
		}
	};

	if (params.flat != null) {
		if (typeof params.flat == "string")
			params.flat = document.getElementById(params.flat);
		if (!params.flat) {
			alert("Calendar.setup:\n  Flat specified but can't find parent.");
			return false;
		}
		var cal = new Calendar(params.firstDay, params.date, params.onSelect || onSelect);
		cal.showsOtherMonths = params.showOthers;
		cal.showsTime = params.showsTime;
		cal.time24 = (params.timeFormat == "24");
		cal.params = params;
		cal.weekNumbers = params.weekNumbers;
		cal.setRange(params.range[0], params.range[1]);
		cal.setDateStatusHandler(params.dateStatusFunc);
		cal.getDateText = params.dateText;
		if (params.ifFormat) {
			cal.setDateFormat(params.ifFormat);
		}
		if (params.inputField && typeof params.inputField.value == "string") {
			cal.parseDate(params.inputField.value);
		}
		cal.create(params.flat);
		cal.show();
		return false;
	}

	var triggerEl = params.button || params.displayArea || params.inputField;
	triggerEl["on" + params.eventName] = function() {
		var dateEl = params.inputField || params.displayArea;
		var dateFmt = params.inputField ? params.ifFormat : params.daFormat;
		var mustCreate = false;
		var cal = window.calendar;
		if (dateEl)
		{
			params.date = Date.parseDate(dateEl.value || dateEl.innerHTML, dateFmt);
		}
		if (!(cal && params.cache)) {
			window.calendar = cal = new Calendar(params.firstDay,
							     params.date,
							     params.onSelect || onSelect,
							     params.onClose || function(cal) { cal.hide(); });
			cal.showsTime = params.showsTime;
			cal.time24 = (params.timeFormat == "24");
			cal.weekNumbers = params.weekNumbers;
			mustCreate = true;
		} else {
			if (params.date)
				cal.setDate(params.date);
			cal.hide();
		}
		if (params.multiple) {
			cal.multiple = {};
			for (var i = params.multiple.length; --i >= 0;) {
				var d = params.multiple[i];
				var ds = d.print("%Y%m%d");
				cal.multiple[ds] = d;
			}
		}
		cal.showsOtherMonths = params.showOthers;
		cal.yearStep = params.step;
		cal.setRange(params.range[0], params.range[1]);
		cal.params = params;
		cal.setDateStatusHandler(params.dateStatusFunc);
		cal.getDateText = params.dateText;
		cal.setDateFormat(dateFmt);
		if (mustCreate)
			cal.create();
		cal.refresh();
		
		if (!params.position)
		{ 
		    //alert("bem no position!");		      
			//cal.showAtElement(params.button || params.displayArea || params.inputField, params.align);
			cal.showAtCursorPosition(10,10);
		}
		else
		{
		    // alert(params.position[0] + " - " +params.position[1]);
			cal.showAt(params.position[0], params.position[1]);
		}
		return false;
	};

	return cal;
};

/**********************************************************************************
/* functions to get corrected mouse position to place calender in view pt at cursor
**********************************************************************************/


function truebody(){
	return (!window.opera && document.compatMode && document.compatMode!="BackCompat") 
		? document.documentElement : document.body
}

var MouseCursor = {x:0, y:0};
document.onmousemove = getCursorPos;

function getCursorPos(e) {		
    var cursor = {x:0, y:0};   
    if (typeof e != "undefined") {
        cursor.x = e.pageX;
        cursor.y = e.pageY;      
    } 
    else if (typeof window.event !="undefined"){
		cursor.x = truebody().scrollLeft+event.clientX
		cursor.y = truebody().scrollTop+event.clientY		
	}
    MouseCursor=cursor;
    return cursor;
}

function findPosX(obj){
	try{
		var curleft=0;
		if(obj){
		if(obj.offsetParent){
			while(obj.offsetParent){
				curleft+=obj.offsetLeft
				obj=obj.offsetParent;}}
		else if(obj.x)
			curleft+=obj.x;}
		return curleft;}
	catch(err){return curleft;}	
}
function findPosY(obj){
	try{
		var curtop=0;
		if(obj){
		if(obj.offsetParent){
			while(obj.offsetParent){
				curtop+=obj.offsetTop
				obj=obj.offsetParent;}}
		else if(obj.y)
			curtop=obj.y;}
		return curtop;}
	catch(err){return curtop;}
}
getViewportScrollX = function() {
	var scrollX = 0;
	if( document.documentElement && document.documentElement.scrollLeft ) {
		scrollX = document.documentElement.scrollLeft;
	}
	else if( document.body && document.body.scrollLeft ) {
		scrollX = document.body.scrollLeft;
	}
	else if( window.pageXOffset ) {
		scrollX = window.pageXOffset;
	}
	else if( window.scrollX ) {
		scrollX = window.scrollX;
	}
	return scrollX;
};
getViewportScrollY = function() {
	var scrollY = 0;
	if( document.documentElement && document.documentElement.scrollTop ) {
		scrollY = document.documentElement.scrollTop;
	}
	else if( document.body && document.body.scrollTop ) {
		scrollY = document.body.scrollLeft;
	}
	else if( window.pageYOffset ) {
		scrollY = window.pageYOffset;
	}
	else if( window.scrollY ) {
		scrollY = window.scrollY;
	}
	return scrollY;
};
getViewportWidth = function() {
	var width = 0;
	if( document.documentElement && document.documentElement.clientWidth ) {
		width = document.documentElement.clientWidth;
	}
	else if( document.body && document.body.clientWidth ) {
		width = document.body.clientWidth;
	}
	else if( window.innerWidth ) {
		width = window.innerWidth - 18;
	}
	return width;
};
getViewportHeight = function() {
  var height = 0;
  if( document.documentElement && document.documentElement.clientHeight ) {
    height = document.documentElement.clientHeight;
  }
  else if( document.body && document.body.clientHeight ) {
    height = document.body.clientHeight;
  }
  else if( window.innerHeight ) {
    height = window.innerHeight - 18;
  }
  return height;
};


Calendar.prototype.showAtCursorPosition = function (offsetX, offsetY) {
	//debugger;
	var self = this;
	if( document.getElementById ) {
		// Get a reference to divTest and measure its width and height.
//		var div = document.getElementById(divName);		
//		var divWidth = div.offsetWidth ? div.offsetWidth : div.style.width ? parseInt( div.style.width ) : 0;
//		var divHeight = div.offsetHeight ? div.offsetHeight :  div.style.height ? parseInt( div.style.height ) : 0;
		
		//alert("offset-w="+ self.element.offsetWidth  + ", offset-h=" + self.element.offsetHeight);
		//alert("style-w="+ self.element.style.width + ", style-h=" + self.element.style.height);
		//alert("w="+ divWidth + ", div-h=" + divHeight);
		
//		var divWidth = self.element.offsetWidth;
//		var divHeight = self.element.offsetHeight;
		
		// total hack right now.. hard code the expected size of the calendar div
		var divWidth = 205
		var divHeight = 160;		
		
		// set position of div to the Right and bottom of cursor position
		var setX = MouseCursor.x + offsetX;
		var setY = MouseCursor.y + offsetY;

		//alert("MouseCursor.x:" + MouseCursor.x+ " setX: " + setX + " viewportWidth: " + getViewportWidth() + " getViewportScrollX()" + getViewportScrollX());		
		//alert("MouseCursor.y:" + MouseCursor.y+ " setY: " + setY + " viewportHeight: " + getViewportHeight()+ " getViewportScrollY()" + getViewportScrollY());		

		// overflowing right of page
		if(setX + divWidth > getViewportWidth() + getViewportScrollX()){
			// try setting it left of cursor
			setX = MouseCursor.x - divWidth - offsetX;
		}	
		// overflowing bottom of page
		if(setY + divHeight > getViewportHeight() + getViewportScrollY()){	
			// try setting above curor
			setY = MouseCursor.y - divHeight - offsetY;
		}	
		// If setX or setY have become smaller than 0, make them 0.
		if( setX < 0 ) setX = 0;
		if( setY < 0 ) setY = 0;
		
		//alert("setX: " + setX +  " sety: " + setY);
		self.showAt(setX, setY);
	
	}
}
