/**
 * This document adss functionality to Actinic to choose a set amount of dates that a 
 * product can be delivered on.
 * Modification note is at the end of the docment.
 * Copyright teclan 2008.
 */

$C = function (name, options){
  return Element.extend(Object.extend(document.createElement(name || "div"), options || {})); 
}

/**Calendar**/

var EventDispatcher = Class.create();
Object.extend(EventDispatcher.prototype, {
   buildListenerChain : function(){
      if(!this.listenerChain)this.listenerChain = {};							
   }, 
   addEventListener : function(type, listener) {
      this.buildListenerChain();
      if(!this.listenerChain[type]) this.listenerChain[type] = [listener];
      else this.listenerChain[type].push(listener);
   },
   hasEventListener : function(type) {
      return (typeof this.listenerChain[type] != "undefined");
   }, 
   removeEventListener : function(type, listener) {
      if(!this.hasEventListener(type)) return false;
      for (var i = 0; i < this.listenerChain[type].length; i++) {
         if(this.listenerChain[type][i] == listener) this.listenerChain[type].splice(i, 1);
	  }
   }, 
   dispatchEvent : function(type, args) {
      this.buildListenerChain();
 	  if(!this.hasEventListener(type))
        return false;
		this.listenerChain[type].any(function(f){ return (f(args) == false ? true : false); });						
   },
   on : function(type, listener) {
      this.addEventListener(type, listener);
   },
   fire : function(type, args) {
      this.dispatchEvent(type, args);
   }
});

//GridBase2
var GridBase = function(){};
	
Object.extend(Object.extend(GridBase.prototype, EventDispatcher.prototype), {
   setTable : function(table) {
      this.table = $(table);
   }, 
   getCell : function(row, cell) {
      return this.table.down("tr", row).down("td", cell);
   }, 
   createListener : function() {
      this.createCellListener();
      this.createRowListener();
      this.createTableListener();
   }, 
   applyBehavior : function() {
      this.table.getElementsBySelector("td").each(this.attachCellListener.bind(this));
      this.table.getElementsBySelector("td").each(this.attachRowListener.bind(this));
      this.attachTableListener(this.table);			
   }, 
   createCellListener : function() {
      this.cellOverHandle = this.handleCellOver.bindAsEventListener(this);
      this.cellOutHandle = this.handleCellOut.bindAsEventListener(this);
      this.cellClickHandle = this.handleCellClick.bindAsEventListener(this);
      this.cellDownHandle = this.handleCellDown.bindAsEventListener(this);
      this.cellUpHandle = this.handleCellUp.bindAsEventListener(this);
   }, 
   createRowListener : function() {
      this.rowOverHandle = this.handleRowOver.bindAsEventListener(this);
      this.rowOutHandle = this.handleRowOut.bindAsEventListener(this);
   }, 
   createTableListener : function() {
      this.tableOverHandle = this.handleTableOver.bindAsEventListener(this);
      this.tableOutHandle = this.handleTableOut.bindAsEventListener(this);
      this.tableDownHandle = this.handleTableDown.bindAsEventListener(this);
      this.tableUpHandle = this.handleTableUp.bindAsEventListener(this);				
   }, 
   attachCellListener : function(cell) {
      Event.observe(cell, "click", this.cellClickHandle);
      Event.observe(cell, "mouseover", this.cellOverHandle);
      Event.observe(cell, "mouseout", this.cellOutHandle);
   }, 
   attachRowListener : function(row) {
      Event.observe(row, "mouseover", this.rowOverHandle);
      Event.observe(row, "mouseout", this.rowOutHandle);
   }, 
   attachTableListener : function(table) {
      Event.observe(table, "mouseover", this.tableOverHandle);
      Event.observe(table, "mouseout", this.tableOutHandle);
      Event.observe(table, "mousedown", this.tableDownHandle);
      Event.observe(table, "mouseup", this.tableUpHandle);
   }, 
   handleCellOver : function(e) {
      this.dispatchEvent("cellover", e);
      if (this.mouseDown == true) this.dispatchEvent("celldown", e);
   }, 
   handleCellOut : function(e) {
      this.dispatchEvent("cellout", e);
   }, 
   handleCellUp : function(e) {
      this.dispatchEvent("cellup", e);
   }, 
   handleCellDown : function(e) {
      this.dispatchEvent("celldown", e);
   },
   handleCellClick : function(e) {
      this.dispatchEvent("cellclick", e);
   }, 
   handleRowOver : function(e) {
      this.dispatchEvent("rowover", e);
   }, 
   handleRowOut : function(e) {
      this.dispatchEvent("rowout", e);
   }, 
   handleTableOver : function(e) {
      this.dispatchEvent("tableover", e);						
   }, 
   handleTableOut : function(e) {
      this.dispatchEvent("tableout", e);
   }, 
   handleTableDown : function(e) {
      this.mouseDown = true;
      this.dispatchEvent("tabledown", e);
   }, 
   handleTableUp : function(e) {
      this.mouseDown = false;
      this.dispatchEvent("tableup", e);
   }
});

//GridBuild
if (!$C) {
   $C = function (name, options) {
      return Element.extend(Object.extend(document.createElement(name || "div"), options || {})); 
   }
}

var GridBuild = function(){};
	
Object.extend(Object.extend(GridBuild.prototype, GridBase.prototype), {
   buildGrid : function(col, row) {
      var table = $C("table");
      var tbody = $C("tbody");
      //a lexical flex
      row.times(function(itr) {											
         var elerow = $C("tr");
         col.times(function(index) {
            elerow.appendChild($C("td"));
         });
         tbody.appendChild(elerow);
      });
      table.appendChild(tbody);
      return table;
   }, 
   loadJSON : function(dto) {
      dto.each(this.iterateRow.bind(this));
   }, 
   loadXML : function(xml) {
      $A(xml.getElementsByTagName("row")).each(this.iterateRowXML.bind(this))
   }, 
   iterateRowXML : function(row, itr) {
      try {
         $A(row.getElementsByTagName("cell")).each(this.applyCellXML.bind(this, itr));
      }
      catch(e) {
         console.log(e);
      }
   }, 					
   iterateRow : function(rowArr, itr) {
      rowArr.each(this.applyCellJSON.bind(this, itr));
   }, 
   applyCellXML : function(row, obj, cell) {
      var cellNode = this.getCell(row, cell);
      if (cellNode) {
         cellNode.innerHTML = obj.firstChild.nodeValue;
	  }
   }, 
   applyCellJSON : function(row, obj, cell) {
      var cellNode = this.getCell(row, cell);
      if (cellNode) {
         Object.extend(cellNode, obj || {});
      }
   }
});

//Calendar select
var CalendarSelect = Class.create();
	
Object.extend(Object.extend(CalendarSelect.prototype, GridBuild.prototype), {
   initialize : function(container, options) {
	  var d = leadDate;
	  //d.setDate(16);
	  d.setMonth(d.getMonth() - 1);
      d.setHours(0);
      d.setMinutes(0);
      d.setSeconds(0);
      d.setMilliseconds(0);
      this.options = Object.extend({ weekLength : 7, endWeek : 6, date : d}, options || {});
      this.container = $(container);
      this.range = this.buildCalendarRange(this.options.date);
      this.monthDTO = this.buildCalendarDTO(this.range);
      this.createTable(this.monthDTO);
      this.createListener();
      this.applyBehavior();
      this.loadJSON(this.monthDTO);
   }, 
   getCell : function(row, cell) {
      var ret = this.tbody.childNodes[row].childNodes[cell];
      return ret ? ret : GridBuild.prototype.getCell.apply(this, arguments);
   }, 
   createListener : function() { 
      GridBuild.prototype.createListener.apply(this, arguments);
      this.dayClickHandle = this.handleDayClick.bindAsEventListener(this);
   }, 
   createTable : function(arr) {
      var table = this.buildGrid(this.options.weekLength, arr.length);
      this.setTable(table);
	  this.container.appendChild(this.table);
	  this.tbody = table.getElementsByTagName("tbody").item(0);
   }, 
   buildCalendarRange : function(date, month) {
      return new GregorianCalendar(date, month);
   }, 
   applyCellJSON : function(row, obj, cell) {
      var cellNode = this.getCell(row, cell);
      if (!(cellNode && obj instanceof Date)) return false;
      //if it passed test it must be a valid day, so apply a dateclick observer
      cellNode.innerHTML = obj.getDate();
	  
	  if (obj.getDay() == 0) {  //|| obj.getDay() == 6) { - commented to enabled saturdays - 28/10/09-teclan
		this.disableCell(cellNode);
	  }
	  else {
		 cellNode.date = obj;
		
if (obj.getDate() == 25 && obj.getMonth() == 11) {
   this.disableCell(cellNode);
}

		 if (excludes) {
			for (var i = 0; i < excludes.length; i++) {
			   if (obj.roughCompare(excludes[i])) {
				  this.disableCell(cellNode);
			   }
			}
		 }
	     Event.observe(cellNode, "click", this.dayClickHandle);
	  }		
   }, 
   buildCalendarDTO : function(range) {
      var monthArr = [];
      var week = [];								
      //load offset with bogus data
      range.start.getDay().times(function(itr){ week.push(undefined) });
      var self = this;
      range.each(function(date){
         week.push(date);
         if (date.getDay() == self.options.endWeek) {
            monthArr.push(week);
            week = [];
         }
      });
      if (week.length > 0) monthArr.push(week);
      return monthArr;
   }, 
   handleDayClick : function(e) {
      this.dispatchEvent("dayclick", Event.element(e).date);
   },
   disableCell : function(cellNode) {
      cellNode.style.backgroundColor = "#333";
	  cellNode.style.color = "#333";
	  cellNode.style.cursor = "default";
   }
});

var MONTHS = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];
var DAYS = ["Sun", "Mon", "Tues", "Wed", "Thurs", "Fri", "Sat"];

//Gregorian Calendar
Date.prototype.succ = function() {
   var ret = new Date(this.getTime());
   ret.setDate(this.getDate() + 1);
   return ret;
}
Date.prototype.isLeapYear = function() {
   var year = this.getFullYear();
   return ((year & 3) == 0 && (year % 100 || (year % 400 == 0 && year)));
}

Date.prototype.roughCompare = function(that) {
   return this.getDate() == that.getDate() && 
          this.getMonth() == (that.getMonth() - 1) &&
		  this.getYear() == that.getYear();
}

Date.prototype.getMonthName = function() {
   return MONTHS[this.getMonth()];
}

Date.prototype.getActualYear = function() {
   var x = this.getYear();
   var y = x % 100;
   y += (y < 38) ? 2000 : 1900;
   return y;
}

Date.prototype.formatDate = function() {
   return DAYS[this.getDay()] + " " + (this.getDate() < 10 ? ("0" + this.getDate()) : this.getDate()) + " " + this.getMonthName() + " " + this.getActualYear();
}

var GregorianCalendar = Class.create();
	
Object.extend(Object.extend(GregorianCalendar.prototype, ObjectRange.prototype), {
   MONTH_MAP : ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"],
   //             J  F  M  A  M  J  J  A  S  O  N  D
   DAY_MAX_MAP : [31,00,31,30,31,30,31,31,30,31,30,31],
   initialize : function(year, month) {
      this.date = this.buildDate(year, month);
	  this.start = this.buildStart(this.date);
	  this.end = this.buildEnd(this.date);
   }, 
   buildDate : function(year, month) {
      var d = false;
      if (year instanceof Date) {
         d = year;
      }
      else {
         d = new Date();
		 d.setYear(year);
         d.setMonth(month);
      }
 	  d.setDate(1);
      d.setHours(0);
      d.setMinutes(0);
      d.setSeconds(0);
      d.setMilliseconds(0);
      return d;
   }, 
   buildStart : function(date) {
      return new Date(date.getTime());
   }, 
   buildEnd : function(date) {
      var month = date.getMonth();
      var maxDays = this.DAY_MAX_MAP[month];
      if(maxDays == 0) maxDays = this.getFebruaryMax();
      this.setMaxDays(maxDays);
      return new Date(date.getFullYear(),date.getMonth(),maxDays);
   }, 
   getFebruaryMax : function() {
      return (this.date.isLeapYear()) ? 29 : 28;
   }, 
   setMaxDays : function(num) {
      this.maxDays = num;
   }, 
   getMaxDays : function() {
      return this.maxDays || 0;
   }, 
   getNextMonth : function() {
      return this.buildDate(this.date.getFullYear(), this.date.getMonth()+1);
   }, 
   getDate : function() {
      return this.date;
   }, 
   getPreviousMonth : function() {
      return this.buildDate(this.date.getFullYear(), this.date.getMonth()-1);
   }, 
   succ : function() {
      return new GregorianCalendar(this.getNextMonth());
   }
});

//Date select
var DateSelect = Class.create();
	
Object.extend(Object.extend(DateSelect.prototype, CalendarSelect.prototype), {
   DOW : ["S","M","T","W","T","F","S"],
   initialize : function(container, options) {
      CalendarSelect.prototype.initialize.apply(this, arguments);
      this.createListener();
      this.controlBar = this.createControlBar();
      this.header = this.createHeader();
      this.injectTable(this.header);
      this.injectTable(this.controlBar);
      this.updateTitle();
   }, 
   createListener : function() {
      CalendarSelect.prototype.createListener.apply(this, arguments);
      this.nextHandle = this.handleNext.bindAsEventListener(this);
      this.prevHandle = this.handlePrev.bindAsEventListener(this);														
   }, 
   updateTitle : function() {
      this.controlBar.titleNode.innerHTML = this.range.MONTH_MAP[this.range.date.getMonth()] + " " + this.range.date.getFullYear();
   }, 
   createControlBar : function() {
      var next = $C("td", { innerHTML : "&gt;", className : "next"});
	  var prev = $C("td", { innerHTML : "&lt;", className : "prev"});
 	  next.observe("click", this.nextHandle);
      prev.observe("click", this.prevHandle);
      var main = $C("td", { className : "main" });
      main.setAttribute("colSpan", 5);
	  var row = $C("tr", { className : "header"});
	  row.titleNode = main;
      row.appendChild(prev);
      row.appendChild(main);
      row.appendChild(next);					
      return row;
   }, 
   createHeader : function() {
      var row = $C("tr", { className : "dow"});
      this.DOW.each(function(itr){
         row.appendChild($C("td", { innerHTML : itr }));
      });
      return row;
   }, 
   rebuildTable : function(date) {
      //remove from parents so the clear won't destroy the elements, hate you IE.
      this.header.parentNode.removeChild(this.header);
      this.controlBar.parentNode.removeChild(this.controlBar);
      this.container.innerHTML = "";//<div class='hide_wk' style='left:0px'></div><div class='hide_wk' style='right:0px'></div>";
      this.range = this.buildCalendarRange(date);
      this.monthDTO = this.buildCalendarDTO(this.range);
      this.createTable(this.monthDTO);
 	  this.applyBehavior();
	  this.loadJSON(this.monthDTO);
	  this.injectTable(this.header);
      this.injectTable(this.controlBar);
      this.updateTitle();
   }, 
   handleNext : function(e) {
      //push the new date a week into the next month
      var date = new Date(this.range.end.getTime());
      date.setDate(date.getDate() + 10);
      this.rebuildTable(date);
   }, 
   handlePrev : function(e) {
      //push the new date a week into the next month
      var date = new Date(this.range.start.getTime());
      date.setDate(date.getDate() - 10);
      this.rebuildTable(date);
   }, 
   injectTable : function(ele) {
      try {
         var tbody = this.table.down("tbody");
         tbody.insertBefore(ele, tbody.firstChild)
      }
      catch(e) { 
         this.table.insertBefore(ele, this.table.firstChild);
      }
   }
});

var $bs = function (id) {
  return document.getElementById(id);
};

/**Initialise calendar**/
function init() {
   var myCalendarSelect = new DateSelect("calendar");
   myCalendarSelect.addEventListener("cellover", function(e) {
      Event.element(e).addClassName("active");
   });
   myCalendarSelect.addEventListener("cellout", function(e) {
      Event.element(e).removeClassName("active");
   });
   myCalendarSelect.addEventListener("dayclick", function(date) {
      if (Date.parse(leadDate) > Date.parse(date)) {
         alert("The date you entered is before our lead delivery date.");
      }
      else {
         $bs("dateInput").value = date.formatDate();
         $bs("calendar").style.display="none";
         $bs("dateDay").value = date.getDate();
         $bs("dateMonth").value = date.getMonthName();
         $bs("dateYear").value = date.getActualYear();
      }
   });
}

if (window.attachEvent) { 
   window.attachEvent("onload", init); 
} 
else {  
   window.addEventListener("load", init, false); 
}

function showCalendar() {
  $bs("calendar").style.display = $bs("calendar").style.display == "block" ? "none" : "block";
}

/*  CPrototype JavaScript framework, version 1.5.1.1
 *  (c) 2005-2007 Sam Stephenson
 *
 *  CPrototype is freely distributable under the terms of an MIT-style license.
 *  For details, see the CPrototype web site: http://www.prototypejs.org/
 *
/*--------------------------------------------------------------------------*/