/*
 * Calendar Emoxion
 * with Mootools
 * Manuel Garcia (thekeeper)
 * http://www.mgarcia.info
 * Version 0.2
 *
 * Copyright (c) 2007 Manuel Garcia
 * http://www.opensource.org/licenses/mit-license.php
 */

/*window.addEvent('domready', function() {
	$$('input.ncalendar').each(function(el){
    el.addEvent('click', function(event) {
				new Calendar(el);
			});
	});
});*/

var Calendar = new Class(
{
   initialize: function(el, Config, open)
   {
      this.input = $(el);
      var lng = new Object();

      // Firefox? IE ?
      try {  var nav = navigator.language.substr(0,2); }
      catch (e)	{ var nav = navigator.userLanguage;}

      lng['en'] =
      {
      	 month : ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'],
         day : ['S','M','T','W','T','F','S'],
         first: 0 // Sunday
      };
      lng['es'] =
      {
      	 month : ['Enero','Febrero','Marzo','Abril','Mayo','Junio','Julio','Agosto','Septiembre','Octubre','Noviembre','Diciembre'],
      	 day : ['L','M','M','J','V','S','D'],
      	 first: 1 // First day of week => Monday
      };
      lng = (!lng[nav])? lng['en'] : lng =  lng[nav] ;
      /* configuration */
      if (!Config) this.config = {format: 'm/d/Y', Lng: lng, isDraggable: true, isClose: true, imgNext: '/i/UI/calendar/next.png', imgPrev: '/i/UI/calendar/prev.png', imgCancel: '/i/UI/calendar/cancel.gif'};
      else
      {
         this.config = Config;
         if (!Config.format) this.config.format = 'm/d/Y';
         if (!Config.Lng) this.config.Lng = lng;
         if (!Config.imgNext) this.config.imgNext = '/i/UI/calendar/next.png';
         if (!Config.imgPrev) this.config.imgPrev = '/i/UI/calendar/prev.png';
         if (!Config.imgCancel) this.config.imgCancel = '/i/UI/calendar/cancel.gif';
      }
      this.month_name = this.config.Lng.month;
      this.day_name =  this.config.Lng.day;
      this.create_calendar();
   },

   create_calendar: function()
   {
      var position = this.input.getCoordinates();
      if ($('ncalendar')) $('ncalendar').remove();
      // content div  //
      if (this.config.isDraggable)
      {
         this.div = new Element('div').setStyles({'top':(position.top+position.height)+'px', 'left':(position.left)+'px'}).setProperty('id', 'ncalendar').injectInside(document.body);
         this.div.makeDraggable();
      }
      else
      {
      	 this.div = new Element('div').setStyles({'top':(position.top+position.height)+'px', 'left':(position.left)+'px'}).setProperty('id', 'ncalendar_' + this.input.id).injectInside(this.input);
      	 this.div.className = 'calendar';
      }
      if (this.config['isDraggable']) this.div.makeDraggable();
      this.nav();
      if (this.input.getProperty('value'))
      {
         var date = this.format_date(this.input.getProperty('value'), this.config.format, 'd/m/Y');
         this.setdate(date);
      }
      else this.setdate();
      this.effect(this.div, 'show');
      this.div.style.display = '';
   },

   nav: function (today)
   {
      // nav
      this.calendardiv = new Element('div').injectInside(this.div);
      this.title = new Element('strong').injectInside(this.calendardiv);
      // next month
      this.next = new Element('img').setProperty('src', this.config.imgNext).injectAfter(this.title);
      // before month
      this.before = new Element('img').setProperty('src', this.config.imgPrev).injectBefore(this.title);
      // close
      if (this.config.isClose)
      {
         this.close = new Element('img').setProperty('src', this.config.imgCancel).injectAfter(this.next);
         this.close.addEvent('click', function(e) {localThis.div.remove();});
      }
      // table
      this.table = new Element('table').injectInside(this.div);
      var thead = new Element('thead').injectInside(this.table);
      var tr = new Element('tr').injectInside(thead);
      this.day_name.each(function (day) {var td = new Element('th').appendText(day).injectInside(tr);});
      var localThis = this;
   },

   setdate : function(date)
   {
      // reset event nav
      this.next.removeEvents('click');
      this.before.removeEvents('click');
      if (!this.validate_date(date))
      {
          this.today = new Date();
		  this.today.setDate(1);
      }
      else
      {
      	 var dateinp = date.split('/');
         this.today = new Date(dateinp[2], dateinp[1] - 1, dateinp[0], 0, 0, 0);
      }
      this.next_m = this.today.getMonth();
      this.next_m++;

      try { this.title.innerHTML = this.month_name[this.today.getMonth()] + ' ' + this.today.getFullYear(); }
      catch (e) { this.title.innerText = this.month_name[this.today.getMonth()] + ' ' + this.today.getFullYear(); }
  	  var localThis = this;

      // event next
      this.next.addEvent('click', function(e)
      {
         var date = localThis.today;
         date.setMonth(localThis.next_m + 1, 1);
	     localThis.tbody.remove();
         localThis.setdate(date.getDate() + '/' + date.getMonth() + '/' + date.getFullYear());
  	  });
  	  // event before
      this.before.addEvent('click', function(e)
      {
         var date = localThis.today;
     	 date.setMonth(localThis.next_m - 1, 1);
         localThis.tbody.remove();
         localThis.setdate(date.getDate() + '/' + date.getMonth() + '/' + date.getFullYear());
  	  });
      var LastMonth = new Date(this.today.getFullYear(), this.next_m - 2, 1, 0, 0, 0);
      var last = LastMonth.getMonth();
      // total days the last month
      var counter = 0;
      for (var b = 1; b <= 31; b++)
      {
         LastMonth.setDate(b);
 		 if (LastMonth.getMonth() == last) counter++;
      }
      this.tbody = new Element('tbody').injectInside(this.table);
      var first_day = this.today;
      var last_day = this.today;
      this.month = this.today.getMonth();
   	  var tr = new Element('tr').injectInside(this.tbody);
  	  var day = 0;
      /* first day week */
      first_day.setDate(1);
      var rest = (!first_day.getDay()) ? 6: first_day.getDay() - 1;
      counter = counter - rest - 1;
      for (var i= this.config.Lng.first; i <= 6; i++)
      {
      	 if (first_day.getDay() == i) break;
         else
         {
			counter++;
			LastMonth.setDate(counter);
			if (LastMonth.getMonth() == this.today.getMonth()) LastMonth.setMonth(this.today.getMonth() - 1);
            this.create_td(tr, counter, LastMonth, 'noday');
         }
      }
      (this.config.Lng.first) ? brea_k = 1 : brea_k = 0;
      /* everydays */
      var date_s = this.today;
      var class_Css;
      var brea_k; // breaking week
  	  var daycounter = 0;
      for (var i = 1; i <= 31; i++)
      {
    	 date_s.setDate(i);
 		 if (date_s.getMonth() == this.month)
 		 {
       		daycounter++;
		    if (date_s.getDay() == brea_k) var tr = new Element('tr').injectInside(this.tbody);
            class_Css = (!date_s.getDay())? 'sunday' : '';
			this.create_td(tr, i, date_s, class_Css);
         }
      }
      this.today.setMonth(this.month);
      this.today.setDate(daycounter);
      var NextMonth = new Date(this.today.getFullYear(), this.today.getMonth() + 1, 1, 0, 0, 0);
      // finish month
      var num = date_s.getDay();
      num = (brea_k) ? 7 - num : 6 - num;
      var b;
      b = (brea_k)? 0 : 6 ;
      if (this.today.getDay() != b)
      {
         for (var i= 1; i <= (num); i++)
         {
            NextMonth.setDate(i);
			this.create_td(tr,i,NextMonth,'noday');
         }
      }
      this.effect(this.tbody, 'show');
   },

   create_td: function(tr, i, date, class_Css)
   {
      var localThis = this;
      var td = new Element('td');
      if (date)
      {
         var dia = date.getDate();
         var mes = (date.getMonth() + 1);
         //  9 to 09 or another number <= 9
         if (dia <= 9) dia = "0" + dia;
         if (mes <= 9) mes = "0" + mes;
         td.setProperty('id', this.format_date(dia + '/'+ mes +'/'+	date.getFullYear(), 'd/m/Y', this.config.format));
      }
      var click = this.config.onclick;
      var draggable = this.config.isDraggable;
      td.addEvent('click', function(e)
      {
         if (click) eval(click + '("' + this.id + '")');
         if (draggable)
         {
            localThis.input.value = this.id;
            localThis.effect(localThis.div, 'fade');
            localThis.div.remove();
         }
  	  });
  	  td.addEvent('mouseover', function(e) {this.addClass('dayselected');});
  	  td.addEvent('mouseout', function(e) {this.removeClass('dayselected');});
      if (class_Css) td.addClass(class_Css);
      // Today ??
      var today = new Date();
      today = today.getDate() + "/" + (today.getMonth()+1) + "/" + today.getFullYear();
      if (date) var date_td = date.getDate() + "/" + (date.getMonth()+1) + "/" + date.getFullYear();
      if (today == date_td) td.addClass('isToday');
      if (this.config.dates && this.config.dates.contains(td.id)) td.addClass('isCoolDate');
  	  td.appendText(i);
      td.injectInside(tr);
   },

   effect: function(div, op)
   {
      var ef = new Fx.Style(div, 'opacity', {duration: 500, transition: Fx.Transitions.quartInOut});
      (op == 'fade') ? ef.start(1,0) : ef.start(0,1);
   },

   validate_date: function(date)
   {
      if (date == undefined) return false;
      var regex = /^(\d{1,2})\/(\d{1,2})\/(\d{4})$/;
      return date.test(regex);
   },

   format_date: function(date, informat, outformat)
   {
      if (!date) return;
      var inarr = informat.split("/");
      var outarr = outformat.split("/");
      var datearr = date.split("/");
      var d = "";
      for (var i=0; i<3; i++) datearr[inarr[i]] = datearr[i];
      for (var i=0; i<3; i++) d += datearr[outarr[i]]+"/";
      return d.substr(0, d.length-1);
   }
});
