﻿/**
 * Version: 1.0 
 * Build Date: 05.02.2010.
 * 
 * Basit Qadeer.
 *   
 * License: Licensed under The MIT License.  
 * Website: http://www.cic.de
 */


var Kalender = function CICKalender(containerId, setting) {


  // the default options.
  this.options = {
		onSelect : this.empty,
		orientation : 'horizontal' ,
		height : '200',
		width : '',
		calendars : 3,
		language : 'de',
		maxDate : '',
		minDate : '',
		startDay : 1,
		monthSelector : 1,
		nextLinkText: 'weiter',
    previousLinkText: 'zur&uuml;ck',
		dateList: '',
		showMonthName:1,
		showNavigation:1,
		monthNames: ['Januar', 'Februar', 'M&aumlrz', 'April', 'Mai', 'Juni', 'Juli', 'August', 'September', 'Oktober', 'November', 'Dezember'],
		dayNames: ['So', 'Mo', 'Di', 'Mi', 'Do', 'Fr', 'Sa'],
		className: 'kalender',
		navigationPosition: 'bottom'
	}
  this.DEFAULT_DATE = new Date(1970,0,1,0,0,0);
  
  if(setting !== undefined ) {
      for (var property in setting)
      this.options[property] = setting[property];
  }
	if(!this.options.dateList) {
		this.options.dateList = '';
	}

  this.months = this.options.monthNames;
  this.days = this.options.dayNames;
  
	this.next_month = this.options.nextLinkText;
  this.next_month_disabled  = "";//config.language[this.options['language']].next_month_disabled ;

  this.previous_month = this.options.previousLinkText;
  this.previous_month_disabled  = "";//config.language[this.options['language']].previous_month_disabled ;
  
  
	// Now
	this.d = new Date();

 	//maximum date.
 	this.maxDate = (this.options.maxDate == '') ? this.DEFAULT_DATE : this.toDate(this.options.maxDate);

 	//minimum date.
 	//this.minDate = (this.options.minDate == '') ? this.DEFAULT_DATE : this.toDate(this.options.minDate);
  this.setMinDate(this.options.minDate)  
  //adjust clander startdate according to the mindate.
/*  if(this.minDate > this.d) {
    this.d.setDate(this.minDate.getDate());
    this.d.setMonth(this.minDate.getMonth());
   this.d.setFullYear(this.minDate.getFullYear());
  }*/
  //if(this.minDate < this.d)
  //  this.minDate = this.d;
  // access month number from current date.
  //this.month = this.minDate.getMonth();
   
  // access day of month from current date.
  //this.date = this.d.getDate();
  
  // access day of week from current date.
  //var day = this.d.getDay();

	// keeps reference of the selected date.
	if(this.options.startDate == undefined || this.options.startDate == '')
	 this.selectedDate = '';
	else {
    this.selectedDate = this.toDate(this.options.startDate);
    this.d.setMonth(this.selectedDate.getMonth());
		this.d.setFullYear(this.selectedDate.getFullYear());
	}

	// access first day of the week from start of month.
  this.d.setDate(1);
	this.firstDay = this.d.getDay() - this.options.startDay;
	this.d.setDate(this.date);

  // access the 4-digit year from current date.
  this.year = this.d.getFullYear();
  
  this.containerId = (containerId !== null) ?  containerId: "calContainer";
  
  this.calElem = document.getElementById(this.containerId);
  
  this.id = 'id'; 
	}
	
  Kalender.prototype.toString = function()  {
		return "[object Kalendar]";
	}
  Kalender.prototype.setMinDate = function(minDate) {
    this.minDate = (!minDate || minDate == '') ? this.DEFAULT_DATE : this.toDate(minDate);
      //adjust clander startdate according to the mindate.
  if(this.minDate > this.d) {
    this.d.setDate(this.minDate.getDate());
    this.d.setMonth(this.minDate.getMonth());
    this.d.setFullYear(this.minDate.getFullYear());
  } else if(this.minDate < this.d) {
    this.minDate.setDate(this.d.getDate());
    this.minDate.setMonth(this.d.getMonth());
    this.minDate.setFullYear(this.d.getFullYear());
  }
  
  // access month number from current date.
  this.month = this.minDate.getMonth();
   
  // access day of month from current date.
  this.date = this.d.getDate();
  
  // access day of week from current date.
  var day = this.d.getDay();

  }

  Kalender.prototype.setMaxDate = function (maxDate) {
    this.maxDate = (!maxDate || maxDate == '') ? this.DEFAULT_DATE : this.toDate(maxDate);
  }
  
  Kalender.prototype.getHandle = function(){
    return this;
  }

	Kalender.prototype.getDaysInMonth = function(month) {
	
	  if(month == undefined) {
	    month = this.month;
    }
    return new Date(this.year, month+1, 0).getDate();
   }

  Kalender.prototype.reset = function(date) {
    if(date == undefined) {
      date = this.d;
    }
    
  	this.day = date.getDate();
		this.month = date.getMonth();

		date.setDate(1);
		this.firstDay = date.getDay() - this.options.startDay;
		date.setDate(this.date);
    	this.year = date.getFullYear();
    this.d = 	date;
	}
	
	Kalender.prototype.hide = function() {
		var calContainer = document.getElementById("cal_" + this.containerId);
		if(calContainer)
   	 calContainer.style.display = "none";
  }
  
 	Kalender.prototype.show = function() {
  
   var doc = document;  
   if( window.handle && handle !== this) {
    handle.hide();
   }  
   handle = this;
   
   var monthsBuffer = [];
   var sbuffer = [];
   sbuffer.push('<div class="' + this.options.className + '" id="cal_' + this.containerId + '" onclick="handle.listener(event)"><div onclick="hideCalender(event)" class="calenderclose">&nbsp;</div>'); 
    
   var navigationBuffer = "";
   
   if(this.options.showNavigation == 1)
    navigationBuffer = this.writeNavigation();
   
   for(var calIdx = 0; calIdx < this.options.calendars; calIdx++) {
    hasSelectbox = (this.options.monthSelector == 1 && calIdx == 0 && this.maxDate != this.DEFAULT_DATE && this.minDate != this.DEFAULT_DATE) ? true:false;
    if(calIdx > 0) { this.d.setMonth(this.d.getMonth() +1 ); }
    var activeMonth = this.cloneDate(this.d);

    this.d.setDate(1);
  	this.day = this.d.getDate();
		this.month = this.d.getMonth();
    this.firstDay = this.d.getDay();
	 	this.year = this.d.getFullYear();

 //   if(this.maxDate == this.DEFAULT_DATE || this.d - this.maxDate < 0) {    
      monthsBuffer.push(this.writeMonth (hasSelectbox)); 
  //  }
   }

    if(this.options.orientation.toLowerCase() != 'vertical') {
     monthsBuffer.push('<div style="clear:left"></div>'); 
    }  
   	
    if(this.options.navigationPosition.toLowerCase() == 'top') {
      sbuffer.push(navigationBuffer);
      sbuffer.push(monthsBuffer.join(''));
    } else {
      sbuffer.push(monthsBuffer.join(''));
      sbuffer.push(navigationBuffer);
    }	
     sbuffer.push('</div>'); 
   //resetting the date back.
    this.d.setMonth(this.d.getMonth() - (this.options.calendars - 1) );
    this.calElem.innerHTML = sbuffer.join('');
    
  }	
   
   Kalender.prototype.writeMonth = function(hasSelectbox) {
      var length = this.getDaysInMonth(this.month);
      var today = new Date();
      var doc = document;
      var sbuffer = [];
      
      if(this.options.orientation.toLowerCase() != 'vertical')
       sbuffer.push('<table cellpadding="0" width="' + this.options.width +'px" cellspacing="0" class="month_container" style="float:left">');
      else
       sbuffer.push('<table cellpadding="0" cellspacing="0" class="month_container" >');
       
       if(!hasSelectbox && this.options.showMonthName != 0)
        sbuffer.push('<tr><td colspan="7" valign="top" class="month_name_container"><div class="month_name">' + this.months[this.month] + ' ' + this.year + '</div>');
       else
       sbuffer.push('<tr><td colspan="7" valign="top" class="month_name_container">');
       
        if(hasSelectbox) {
            sbuffer.push('<div>'+this.getSelectbox()+'</div>');
        } 
      sbuffer.push('</td></tr>');
      sbuffer.push('<tr>');

      for( var i = 0 + this.options.startDay ; i < this.days.length + this.options.startDay; i++ )	{
       sbuffer.push('<th class="day_name">' + this.days[i%7] + '</th>');
      }
      sbuffer.push('</tr>');
        
      sbuffer.push('<tr>');
      var startValue = (7- this.options.startDay + this.firstDay) % 7 ;
      
      for(var j = 0; j < 42; j++ ) {
      
        var displayNum = j - startValue + 1;//(j - this.options.startDay + this.d.getDay());
        var dayNumber =  (displayNum + this.firstDay -1)% 7;
        var isLink = false;
        var isActive = false;
        var isWeekend = (dayNumber == 0  || dayNumber == 6) ? true:false;
        var isSelected = false;
        var isToday = false;
        
        if(displayNum > 0 && length >= displayNum) {
          var d = new Date(this.year, this.month, displayNum, 0, 0, 0);
          isLink = this.isLink(d);
          isActive = this.isActive(d);
          isSelected = this.isSelectedDate(d);
          isToday = this.isToday(d);
        }
        
        if( j  <  startValue  || displayNum > length) {
           var _d = this.cloneDate(this.d);
           _d.setDate(displayNum);
           
            if(_d.getDay() == 0 || _d.getDay() == 6 ) {
              sbuffer.push('<td class="weekend_disabled">' + _d.getDate() + '</td>');
            } else {
              sbuffer.push('<td class="date_disabled">' + _d.getDate() + '</td>');
            }  
        } 
        else if (isSelected) {
           sbuffer.push('<td class="date_active" id="'+this.id+'selected" date="' + displayNum+'.'+this.month+'.'+this.year +'">' + displayNum + '</td>');
        }
        else if ( (isToday && isLink && isActive) || (isLink && isActive) ) {
           if(isWeekend) {
            sbuffer.push('<td class="weekend_enabled" date="' + displayNum+'.'+this.month+'.'+this.year +'">' + displayNum + '</td>'); 
           } else {
            sbuffer.push('<td class="date_enabled" date="' + displayNum+'.'+this.month+'.'+this.year +'">' + displayNum + '</td>');
           }
        } else if (isLink && !isActive) {
           if(isWeekend) {
            sbuffer.push('<td class="weekend_inactive" >' + displayNum + '</td>'); 
           } else {
            sbuffer.push('<td class="date_inactive" >' + displayNum + '</td>');
           }
        } else  {
            if(isWeekend) { 
              sbuffer.push('<td class="weekend_disabled" >' + displayNum + '</td>');
            } else {
              sbuffer.push('<td class="date_disabled" >' + displayNum + '</td>');
            }  
        }
                
      if(j%7==6){
       sbuffer.push('</tr>');
       sbuffer.push('<tr>');
      }
      }
      
      sbuffer.push('</tr></table>');
      return sbuffer.join('');
   }
   
   Kalender.prototype.writeNavigation = function() {

		var previousClass = (this.hasPreviousLink()) ? "zurueck" : "zurueck_disabled"
		var nextClass = (this.hasNextLink()) ? "weiter" : "weiter_disabled"
    var sbuffer = [];

		sbuffer.push('<div class="navigation_container">');
		sbuffer.push('<div style="height:13px">&nbsp;</div>');
		sbuffer.push('<div class="' + previousClass + '" id="back" style="float:left">' + this.previous_month  + '</div>');
		sbuffer.push('<div class="' + nextClass + '" id="next" style="float:right">' + this.next_month  + '</div>');
		sbuffer.push('<div style="clear:both;">&nbsp;</div>');
		sbuffer.push('</div>');
		//sbuffer.push('<div style="height:13px">&nbsp;</div>');


/*
    sbuffer.push('<div class="navigation_container">');

    if(this.hasPreviousLink()) {
      sbuffer.push('<div class="back" id="back">' + this.previous_month + '</div>');
    } else {
      sbuffer.push('<div class="back_disabled" >' + this.previous_month_disabled + '</div>');
    }
    if(this.hasNextLink()) {
      sbuffer.push('<div class="next" id="next">' + this.next_month + '</div>');
    }else {
     sbuffer.push('<div class="next_disabled" >' + this.next_month_disabled + '</div>');
    }
     sbuffer.push('<div style="clear:both" ></div>');
     sbuffer.push('</div>');*/
    return sbuffer.join('');

   }
   
    Kalender.prototype.changeDate = function(td, date) {
  		var oDiv = document.getElementById(this.id + "selected");
  		
  		if(oDiv !== null) {
  		  oDiv.className = "days_link";
  		  oDiv.id = "";
  	  }
  		td.className =  "selected";
  		td.id = this.id + "selected";
  		this.date = parseInt(date);
  }
	
	Kalender.prototype.returnDate = function(month, year) {
		var selectedDate = new Date(year, month, this.date, 0, 0, 0);
    this.selectedDate = selectedDate;
		this.options['onSelect'](selectedDate);
		this.hide();
  }
	
  Kalender.prototype.changeMonth = function(e, mo) {
   	if (e && e.stopPropagation) e.stopPropagation();
		else if (window.event && window.event.cancelBubble)
		window.event.cancelBubble = true;

    this.d.setDate(1);
    this.d.setMonth(this.d.getMonth() + mo);
  	this.day = this.d.getDate();
		this.month = this.d.getMonth();
		this.firstDay = this.d.getDay() - this.options.startDay;
	 	this.year = this.d.getFullYear();
   
	  this.show(this);

	}

  Kalender.prototype.cloneDate = function(d) {
    var clone = new Date();
    if(d) {
     	clone.setDate(d.getDate());
  		clone.setMonth(d.getMonth());
  		clone.setYear(d.getFullYear());
    }
		return clone;
  }
  
  Kalender.prototype.toDate = function(str) {
    if(str === undefined) {
      throw "Provided argument must not be null"; 
    }
    var dateArray = str.split(".");
    return new Date(dateArray[2], dateArray[1] - 1, dateArray[0], 0, 0, 0);
  }
  
  Kalender.prototype.isLink = function(d) {
    var response = false;
    if((this.maxDate == this.DEFAULT_DATE || this.maxDate >= d) && (this.minDate == this.DEFAULT_DATE || d >= this.minDate)) {
     response = true;
    }
    return response;
  }
  
  Kalender.prototype.isActive = function(d) {
     var response = false; 
     var dateList = this.options.dateList;
     if(dateList.length == 0 || (dateList.length >= 10 && dateList.indexOf(this.formate(d)) >= 0))
        response = true;
        
     return response;         
  }
  
  Kalender.prototype.isToday = function(d) {
    var response = false;
    var today = new Date();
    today.setHours(0);
    today.setMinutes(0);
    today.setSeconds(0);
    var diff = Math.round(( d - today ) / 86400000) // (86400000 = 1000*60*60*24) 

    if(diff  == 0) {
      response = true;
    }
    return response;
  }
  
  Kalender.prototype.isSelectedDate = function(d) {
    var response = false;
      if( this.selectedDate != '' && Math.round( d - this.selectedDate ) == 0 ) {
       response = true;
      }
    return response;
  }
  
  Kalender.prototype.hasNextLink = function() {
    var response = true;
    var maxMonth = parseInt(this.maxDate.getMonth());
    var maxYear = this.maxDate.getFullYear();
    var displayMonth = parseInt(this.d.getMonth() + this.options.calendars -1);
    var displayYear = this.d.getFullYear();

		var _d = this.cloneDate(this.d);
    _d.setDate(1);  
		_d.setMonth(_d.getMonth() + this.options.calendars);



    if(displayMonth > 11) {
      displayMonth = displayMonth - 12;
      displayYear +=1; 
    }
  //   displayMonth = (displayMonth > 11) ? displayMonth - 12 : displayMonth
/*     
    if(this.maxDate != this.DEFAULT_DATE && maxMonth <= displayMonth && maxYear <= displayYear)
      response = false;
  */
		if(_d.getTime() > this.maxDate.getTime())    
			response = false;

    return response; 
  }
  
  Kalender.prototype.hasPreviousLink = function() {
    var response = true;
    var _d = this.cloneDate(this.d);
    _d.setDate(1);  
   
    if(this.minDate != this.DEFAULT_DATE && _d  - this.minDate < 86400000)
      response = false;
      
    return response;  
  }
  
  Kalender.prototype.showMonth = function(month) {
    var response = true;
    if(parseInt(this.maxDate.getMonth()) < parseInt(month) && parseInt(this.d.getFullYear()) >= parseInt(this.maxDate.getFullYear()))
      response = false;
    return response;  
  }
  
  Kalender.prototype.getSelectbox = function() {
    var sbuffer = [];
    sbuffer.push('<select class="month_selectbox"  onchange="handle.redraw(this)">');
    var to = this.maxDate.getMonth() - this.minDate.getMonth() + (this.maxDate.getFullYear() - this.minDate.getFullYear())*12
    for( var i = 0; i <= to; i++) {
      var _d = new Date();
      _d.setFullYear(this.minDate.getFullYear());
      _d.setMonth(this.minDate.getMonth());
      
      if(i == 0) {
       // _d.setFullYear(this.minDate.getFullYear());
        _d.setDate(this.minDate.getDate());
      } else
         _d.setDate(1);
         
      _d.setMonth(this.minDate.getMonth()+i);
      
      var value = _d.getDate()+ "." + _d.getMonth()+ "." + _d.getFullYear();
      var option = this.months[_d.getMonth()] + " " + _d.getFullYear();
      if(_d.getMonth() == this.d.getMonth() && _d.getFullYear() == this.d.getFullYear())
        sbuffer.push('<option value = "'+ value +'" selected>' + option);
      else
        sbuffer.push('<option value = "'+ value +'">' + option);
    }
    return sbuffer.join('');
   }
  
  Kalender.prototype.redraw = function(refrence) {
    var selIndex = refrence.selectedIndex;
    var selvalue = refrence.options[selIndex].value;
    var selText = refrence.options[selIndex].text;
    if(selIndex + this.options.calendars + 1 > refrence.options.length) {
      var len = refrence.options.length;
      var idx = len - this.options.calendars ;
      selvalue = refrence.options[idx].value;
      this.d.setMonth(selvalue.split('.')[1]);
      this.d.setFullYear(selvalue.split('.')[2]);
    } else {
      this.d.setMonth(selvalue.split('.')[1]);
      this.d.setFullYear(selvalue.split('.')[2]);
    }
    this.show();
  
  }
  
  Kalender.prototype.addEvent = function(node, type, listener) {
    
    if(node.addEventListener) {
      node.addEventListener(type, listener, false);
      return true;
    } else if(node.attachEvent) {
      node['e'+type+listener] = listener;
      node[type+listener] = function() {
          node['e'+type+listener](window.event);
        }
      node.attachEvent('on'+type, node[type+listener]);
      
      return true;  
    }
    return false;
  }
  
  Kalender.prototype.listener = function(W3CEvent) {
    if(W3CEvent.srcElement) {
      var oTarget = W3CEvent.srcElement;
    } else {
      var oTarget = W3CEvent.target;
    }
    if(oTarget.id == 'next') {
      handle.changeMonth(W3CEvent, 1);
    } else if(oTarget.id == 'back') {
      handle.changeMonth(W3CEvent, -1);
    } else if(oTarget.getAttribute('date')){
      var _date = oTarget.getAttribute('date');
      var _date_parts = _date.split('.');
      handle.changeDate(oTarget, _date_parts[0]);
      handle.returnDate(_date_parts[1] , _date_parts[2]);
    }

		if (W3CEvent.stopPropagation)
    	W3CEvent.stopPropagation();
    else
    	W3CEvent.cancelBubble = true;
  }
  
  Kalender.prototype.formate = function(d) {
  
    if(d === undefined ||  !d instanceof Date) {
      throw "Provided argument should be a Date Object."; 
    }
    
    var date = (d.getDate() > 9) ? d.getDate():0+''+d.getDate();
	  var month = (d.getMonth() + 1 > 9)? parseInt(d.getMonth()+1) : 0 +''+ parseInt(d.getMonth()+1);
	  
	  return date + "." + month + "." + d.getFullYear();
  }
