(function($){
    
    $.fn.extend({
        
        renderCalendar  :   function(s)
        {
            var dc = function(a)
            {
                return document.createElement(a);
            };

            s = $.extend({}, $.fn.datePicker.defaults, s);
            if (s.showHeader != $.dpConst.SHOW_HEADER_NONE) {
                var headRow = $(dc('tr'));
                for (var i=Date.firstDayOfWeek; i<Date.firstDayOfWeek+7; i++) {
                    var weekday = i%7;
                    var day = Date.dayNames[weekday];
                    headRow.append(
                        jQuery(dc('th')).attr({
                            'scope':'col', 
                            'abbr':day, 
                            'title':day, 
                            'class':(weekday == 0 || weekday == 6 ? 'weekend' : 'weekday')
                            }).html(s.showHeader == $.dpConst.SHOW_HEADER_SHORT ? day.substr(0, 1) : day)
                        );
                }
            };
			
            var calendarTable = $(dc('table'))
            .attr(
            {
                'cellspacing':2
            }
            )
            .addClass('jCalendar')
            .append(
                (s.showHeader != $.dpConst.SHOW_HEADER_NONE ? 
                    $(dc('thead'))
                    .append(headRow)
                    :
                    dc('thead')
                    )
                );
            var tbody = $(dc('tbody'));
			
            var today = (new Date()).zeroTime();
			
            var month = s.month == undefined ? today.getMonth() : s.month;
            var year = s.year || today.getFullYear();
			
            var currentDate = new Date(year, month, 1);
			
			
            var firstDayOffset = Date.firstDayOfWeek - currentDate.getDay() + 1;
            if (firstDayOffset > 1) firstDayOffset -= 7;
            var weeksToDraw = Math.ceil(( (-1*firstDayOffset+1) + currentDate.getDaysInMonth() ) /7);
            currentDate.addDays(firstDayOffset-1);
			
            var doHover = function(firstDayInBounds)
            {
                return function()
                {
                    if (s.hoverClass) {
                        var $this = $(this);
                        if (!s.selectWeek) {
                            $this.addClass(s.hoverClass);
                        } else if (firstDayInBounds && !$this.is('.disabled')) {
                            $this.parent().addClass('activeWeekHover');
                        }
                    }
                }
            };
            var unHover = function()
            {
                if (s.hoverClass) {
                    var $this = $(this);
                    $this.removeClass(s.hoverClass);
                    $this.parent().removeClass('activeWeekHover');
                }
            };

            var w = 0;
            while (w++<weeksToDraw) {
                var r = jQuery(dc('tr'));
                var firstDayInBounds = s.dpController ? currentDate > s.dpController.startDate : false;
                for (var i=0; i<7; i++) {
                    var thisMonth = currentDate.getMonth() == month;
                    var d = $(dc('td'))
                    .text(thisMonth ? currentDate.getDate() + '' : '  ')
                    .addClass((thisMonth ? 'current-month ' : 'other-month ') +
                        (currentDate.isWeekend() ? 'weekend ' : 'weekday ') +
                        (thisMonth && currentDate.getTime() == today.getTime() ? 'today ' : '')
                        )
                    .data('datePickerDate', currentDate.asString())
                    .hover(doHover(firstDayInBounds), unHover)
                    ;
                    r.append(d);
                    if (s.renderCallback) {
                        s.renderCallback(d, currentDate, month, year);
                    }
                   
                    currentDate = new Date(currentDate.getFullYear(), currentDate.getMonth(), currentDate.getDate()+1);
                }
                tbody.append(r);
            }
            calendarTable.append(tbody);
			
            return this.each(
                function()
                {
                    $(this).empty().append(calendarTable);
                }
                );
        },
        
        datePicker : function(s)
        {			
            if (!$.event._dpCache) $.event._dpCache = [];
			
            // initialise the date picker controller with the relevant settings...
            s = $.extend({}, $.fn.datePicker.defaults, s);
			
            return this.each(
                function()
                {
                    var $this = $(this);
                    var alreadyExists = true;
					
                    if (!this._dpId) {
                        this._dpId = $.event.guid++;
                        $.event._dpCache[this._dpId] = new DatePicker(this);
                        alreadyExists = false;
                    }
					
                    if (s.inline) {
                        s.createButton = false;
                        s.displayClose = true;
                        s.closeOnSelect = false;
                        $this.empty();
                    }
					
                    var controller = $.event._dpCache[this._dpId];
					
                    controller.init(s);
					
                    if (!alreadyExists && s.createButton) {
                        // create it!
                        controller.button = $('<a href="#" class="dp-choose-date" title="' + $.dpText.TEXT_CHOOSE_DATE + '"> <img src="photos/calendar.png" class="ui-datepicker-trigger"></a>')
                        .bind(
                            'click',
                            function()
                            {
                                $this.dpDisplay(this);
                                this.blur();
                                return false;
                            }
                            );
                        $this.after(controller.button);
                    }
					
                    if (!alreadyExists && $this.is(':text')) {
                        $this
                        .bind(
                            'dateSelected',
                            function(e, selectedDate, $td)
                            {
                                this.value = selectedDate.asString();
                                updatePartner(this,selectedDate);
                            }
                            ).bind(
                            'change',
                            function()
                            {
                                if (this.value == '') {
                                    controller.clearSelected();
                                } else {
                                    var d = Date.fromString(this.value);
                                    if (d) {
                                        controller.setSelected(d, true, true);
                                    }
                                }
                            }
                            );
                        if (s.clickInput) {
                            $this.bind(
                                'click',
                                function()
                                {
                                    // The change event doesn't happen until the input loses focus so we need to manually trigger it...
                                    $this.trigger('change');
                                    $this.dpDisplay();
                                }
                                );
                        }
                        var d = Date.fromString(this.value);
                        if (this.value != '' && d) {
                            controller.setSelected(d, true, true);
                        }
                    }
					
                    $this.addClass('dp-applied');
					
                }
                )
        },
       
        dpSetDisabled : function(s)
        {
            return _w.call(this, 'setDisabled', s);
        },
       
        dpSetStartDate : function(d)
        {
            return _w.call(this, 'setStartDate', d);
        },
       
        dpSetEndDate : function(d)
        {
            return _w.call(this, 'setEndDate', d);
        },
        
        dpGetSelected : function()
        {
            var c = _getController(this[0]);
            if (c) {
                return c.getSelected();
            }
            return null;
        },
        
        dpSetSelected : function(d, v, m, e)
        {
            if (v == undefined) v=true;
            if (m == undefined) m=true;
            if (e == undefined) e=true;
            return _w.call(this, 'setSelected', Date.fromString(d), v, m, e);
        },
      
        dpSetDisplayedMonth : function(m, y)
        {
            return _w.call(this, 'setDisplayedMonth', Number(m), Number(y), true);
        },
       
        dpDisplay : function(e)
        {
            return _w.call(this, 'display', e);
        },
       
        dpSetRenderCallback : function(a)
        {
            return _w.call(this, 'setRenderCallback', a);
        },
        
        dpSetPosition : function(v, h)
        {
            return _w.call(this, 'setPosition', v, h);
        },
       
        dpSetOffset : function(v, h)
        {
            return _w.call(this, 'setOffset', v, h);
        },
      
        dpClose : function()
        {
            return _w.call(this, '_closeCalendar', false, this[0]);
        },
        // private function called on unload to clean up any expandos etc and prevent memory links...
        _dpDestroy : function()
        {
        // TODO - implement this?
        }
    });
	
    // private internal function to cut down on the amount of code needed where we forward
    // dp* methods on the jQuery object on to the relevant DatePicker controllers...
    var _w = function(f, a1, a2, a3, a4)
    {
        return this.each(
            function()
            {
                var c = _getController(this);
                if (c) {
                    c[f](a1, a2, a3, a4);
                }
            }
            );
    };
	
    function DatePicker(ele)
    {
        this.ele = ele;
		
        // initial values...
        this.displayedMonth		=	null;
        this.displayedYear		=	null;
        this.startDate			=	null;
        this.endDate			=	null;
        this.showYearNavigation	=	null;
        this.closeOnSelect		=	null;
        this.displayClose		=	null;
        this.rememberViewedMonth=	null;
        this.selectMultiple		=	null;
        this.numSelectable		=	null;
        this.numSelected		=	null;
        this.verticalPosition	=	null;
        this.horizontalPosition	=	null;
        this.verticalOffset		=	null;
        this.horizontalOffset	=	null;
        this.button				=	null;
        this.renderCallback		=	[];
        this.selectedDates		=	{};
        this.inline				=	null;
        this.context			=	'#dp-popup';
        this.settings			=	{};
        this.returnElement	=	null;
    };
    $.extend(
        DatePicker.prototype,
        {	
            init : function(s)
            {
                this.setStartDate(s.startDate);
                this.setEndDate(s.endDate);
                this.setDisplayedMonth(Number(s.month), Number(s.year));
                this.setRenderCallback(s.renderCallback);
                this.showYearNavigation = s.showYearNavigation;
                this.closeOnSelect = s.closeOnSelect;
                this.displayClose = s.displayClose;
                this.rememberViewedMonth =	s.rememberViewedMonth;
                this.selectMultiple = s.selectMultiple;
                this.numSelectable = s.selectMultiple ? s.numSelectable : 1;
                this.numSelected = 0;
                this.verticalPosition = s.verticalPosition;
                this.horizontalPosition = s.horizontalPosition;
                this.hoverClass = s.hoverClass;
                this.setOffset(s.verticalOffset, s.horizontalOffset);
                this.inline = s.inline;
                this.settings = s;
                if (this.inline) {
                    this.context = this.ele;
                    this.display();
                }
            },
            setStartDate : function(d)
            {
                if (d) {
                    this.startDate = Date.fromString(d);
                }
                if (!this.startDate) {
                    this.startDate = sumaDias((new Date()).zeroTime(),1);
                }
                this.setDisplayedMonth(this.displayedMonth, this.displayedYear);
            },
            setEndDate : function(d)
            {
                if (d) {
                    this.endDate = Date.fromString(d);
                }
                if (!this.endDate) {
                    this.endDate = (new Date('12/31/2999')); // using the JS Date.parse function which expects mm/dd/yyyy
                }
                if (this.endDate.getTime() < this.startDate.getTime()) {
                    this.endDate = this.startDate;
                }
                this.setDisplayedMonth(this.displayedMonth, this.displayedYear);
            },
            setPosition : function(v, h)
            {
                this.verticalPosition = v;
                this.horizontalPosition = h;
            },
            setOffset : function(v, h)
            {
                this.verticalOffset = parseInt(v) || 0;
                this.horizontalOffset = parseInt(h) || 0;
            },
            setDisabled : function(s)
            {
                $e = $(this.ele);
                $e[s ? 'addClass' : 'removeClass']('dp-disabled');
                if (this.button) {
                    $but = $(this.button);
                    $but[s ? 'addClass' : 'removeClass']('dp-disabled');
                    $but.attr('title', s ? '' : $.dpText.TEXT_CHOOSE_DATE);
                }
                if ($e.is(':text')) {
                    $e.attr('disabled', s ? 'disabled' : '');
                }
            },
            setDisplayedMonth : function(m, y, rerender)
            {
                if (this.startDate == undefined || this.endDate == undefined) {
                    return;
                }
                var s = new Date(this.startDate.getTime());
                s.setDate(1);
                var e = new Date(this.endDate.getTime());
                e.setDate(1);
				
                var t;
                if ((!m && !y) || (isNaN(m) && isNaN(y))) {
                    // no month or year passed - default to current month
                    t = new Date().zeroTime();
                    t.setDate(1);
                } else if (isNaN(m)) {
                    // just year passed in - presume we want the displayedMonth
                    t = new Date(y, this.displayedMonth, 1);
                } else if (isNaN(y)) {
                    // just month passed in - presume we want the displayedYear
                    t = new Date(this.displayedYear, m, 1);
                } else {
                    // year and month passed in - that's the date we want!
                    t = new Date(y, m, 1)
                }
                // check if the desired date is within the range of our defined startDate and endDate
                if (t.getTime() < s.getTime()) {
                    t = s;
                } else if (t.getTime() > e.getTime()) {
                    t = e;
                }
                var oldMonth = this.displayedMonth;
                var oldYear = this.displayedYear;
                this.displayedMonth = t.getMonth();
                this.displayedYear = t.getFullYear();

                if (rerender && (this.displayedMonth != oldMonth || this.displayedYear != oldYear))
                {
                    this._rerenderCalendar();
                    $(this.ele).trigger('dpMonthChanged', [this.displayedMonth, this.displayedYear]);
                }
            },
            setSelected : function(d, v, moveToMonth, dispatchEvents)
            {
                if (d < this.startDate || d > this.endDate) {
                    // Don't allow people to select dates outside range...
                    return;
                }
                var s = this.settings;
                if (s.selectWeek)
                {
                    d = d.addDays(- (d.getDay() - Date.firstDayOfWeek + 7) % 7);
                    if (d < this.startDate) // The first day of this week is before the start date so is unselectable...
                    {
                        return;
                    }
                }
                if (v == this.isSelected(d)) // this date is already un/selected
                {
                    return;
                }
                if (this.selectMultiple == false) {
                    this.clearSelected();
                } else if (v && this.numSelected == this.numSelectable) {
                    // can't select any more dates...
                    return;
                }
                if (moveToMonth && (this.displayedMonth != d.getMonth() || this.displayedYear != d.getFullYear())) {
                    this.setDisplayedMonth(d.getMonth(), d.getFullYear(), true);
                }
                this.selectedDates[d.toString()] = v;
                this.numSelected += v ? 1 : -1;
                var selectorString = 'td.' +( d.getMonth() == this.displayedMonth ? 'current-month' : 'other-month');
                var $td;
                $(selectorString, this.context).each(
                    function()
                    {
                        if ($(this).data('datePickerDate') == d.asString()) {
                            $td = $(this);
                            if (s.selectWeek)
                            {
                                $td.parent()[v ? 'addClass' : 'removeClass']('selectedWeek');
                            }
                            $td[v ? 'addClass' : 'removeClass']('selected'); 
                        }
                    }
                    );
                $('td', this.context).not('.selected')[this.selectMultiple &&  this.numSelected == this.numSelectable ? 'addClass' : 'removeClass']('unselectable');
				
                if (dispatchEvents)
                {
                    var s = this.isSelected(d);
                    $e = $(this.ele);
                    var dClone = Date.fromString(d.asString());
                    $e.trigger('dateSelected', [dClone, $td, s]);
                    $e.trigger('change');
                }
            },
            isSelected : function(d)
            {
                return this.selectedDates[d.toString()];
            },
            getSelected : function()
            {
                var r = [];
                for(s in this.selectedDates) {
                    if (this.selectedDates[s] == true) {
                        r.push(Date.parse(s));
                    }
                }
                return r;
            },
            clearSelected : function()
            {
                this.selectedDates = {};
                this.numSelected = 0;
                $('td.selected', this.context).removeClass('selected').parent().removeClass('selectedWeek');
            },
            display : function(eleAlignTo)
            {
                if ($(this.ele).is('.dp-disabled')) return;
				
                eleAlignTo = eleAlignTo || this.ele;
                var c = this;
                var $ele = $(eleAlignTo);
                var eleOffset = $ele.offset();
				
                var $createIn;
                var attrs;
                var attrsCalendarHolder;
                var cssRules;
				
                if (c.inline) {
                    $createIn = $(this.ele);
                    attrs = {
                        'id'		:	'calendar-' + this.ele._dpId,
                        'class'	:	'dp-popup dp-popup-inline'
                    };

                    $('.dp-popup', $createIn).remove();
                    cssRules = {
                    };
                } else {
                    $createIn = $('body');
                    attrs = {
                        'id'		:	'dp-popup',
                        'class'	:	'dp-popup'
                    };
                    if (c.horizontalOffset<0) {
                        if (c.verticalOffset<0) {
                            cssRules = {
                            'top'	:	eleOffset.top + c.verticalOffset,
                            'left'	:	eleOffset.left + c.horizontalOffset
                            };
                        } else {
                            cssRules = {
                            'top'	:	eleOffset.top + c.verticalOffset,
                            'left'	:	eleOffset.left + c.horizontalOffset
                            };
                        }
                    } else {
                        if (c.verticalOffset<0) {
                            cssRules = {
                            'top'	:	eleOffset.top,
                            'left'	:	eleOffset.left
                            };
                        } else {
                            cssRules = {
                            'top'	:	eleOffset.top,
                            'left'	:	eleOffset.left
                            };
                        }
                    }
                    var _checkMouse = function(e)
                    {
                        var el = e.target;
                        var cal = $('#dp-popup')[0];
						
                        while (true){
                            if (el == cal) {
                                return true;
                            } else if (el == document) {
                                c._closeCalendar();
                                return false;
                            } else {
                                el = $(el).parent()[0];
                            }
                        }
                    };
                    this._checkMouse = _checkMouse;
					
                    c._closeCalendar(true);
                    $(document).bind(
                        'keydown.datepicker', 
                        function(event)
                        {
                            if (event.keyCode == 27) {
                                c._closeCalendar();
                            }
                        }
                        );
                }
				
                if (!c.rememberViewedMonth)
                {
                    var selectedDate = this.getSelected()[0];
                    if (selectedDate) {
                        selectedDate = new Date(selectedDate);
                        this.setDisplayedMonth(selectedDate.getMonth(), selectedDate.getFullYear(), false);
                    }
                }
				
                $createIn
                .append(
                    $('<div></div>')
                    .attr(attrs)
                    .css(cssRules)
                    .append(
                        //								$('<a href="#" class="selecteee">aaa</a>'),
                        $('<h2></h2>'),
                        $('<div class="dp-nav-prev"></div>')
                        .append(
                            $('<a class="dp-nav-prev-year" href="#" title="' + $.dpText.TEXT_PREV_YEAR + '"><div/></a>')
                            .bind(
                                'click',
                                function()
                                {
                                    return c._displayNewMonth.call(c, this, 0, -1);
                                }
                                ),
                            $('<a class="dp-nav-prev-month" href="#" title="' + $.dpText.TEXT_PREV_MONTH + '"><div/></a>')
                            .bind(
                                'click',
                                function()
                                {
                                    return c._displayNewMonth.call(c, this, -1, 0);
                                }
                                )
                            ),
                        $('<div class="dp-nav-next"></div>')
                        .append(
                            $('<a class="dp-nav-next-year" href="#" title="' + $.dpText.TEXT_NEXT_YEAR + '"><div/></a>')
                            .bind(
                                'click',
                                function()
                                {
                                    return c._displayNewMonth.call(c, this, 0, 1);
                                }
                                ),
                            $('<a class="dp-nav-next-month" href="#" title="' + $.dpText.TEXT_NEXT_MONTH + '"><div/></a>')
                            .bind(
                                'click',
                                function()
                                {
                                    return c._displayNewMonth.call(c, this, 1, 0);
                                }
                                )
                            ),
                        $('<div class="dp-calendar"></div>')
                        )
                    .bgIframe()
                    );
					
                var $pop = this.inline ? $('.dp-popup', this.context) : $('#dp-popup');
				
                if (this.showYearNavigation == false) {
                    $('.dp-nav-prev-year, .dp-nav-next-year', c.context).css('display', 'none');
                }
                if (this.displayClose) {
                    $pop.append(
                        $('<a href="#" id="dp-close">' + $.dpText.TEXT_CLOSE + '</a>')
                        .bind(
                            'click',
                            function()
                            {
                                c._closeCalendar();
                                return false;
                            }
                            )
                        );
                }
                c._renderCalendar();

                $(this.ele).trigger('dpDisplayed', $pop);
				
                if (!c.inline) {
                    iebody = (document.compatMode && document.compatMode != "BackCompat") ? document.documentElement : document.body
                    browserWidth = document.all ? iebody.clientWidth : window.innerWidth;
                    browserHeight = document.all ? iebody.clientHeight : window.innerHeight;
                    viewportLeftBorder = document.all ? iebody.scrollLeft : pageXOffset;
                    viewportTopBorder = document.all ? iebody.scrollTop : pageYOffset;
                    viewportRightBorder = viewportLeftBorder + browserWidth;
                    viewportBottomBorder = viewportTopBorder + browserHeight;
                    calPadding = parseInt(getStyle(document.getElementById("dp-popup"),"paddingTop"));

                    if (this.verticalPosition == $.dpConst.POS_AUTO) {
                        if ((eleOffset.top + $ele.height() + $pop.height()) > viewportBottomBorder) {
                            vertPosition = eleOffset.top + $ele.height() - $pop.height();
                            vertPosition = vertPosition + (calPadding * 2);
                            $pop.css('top', vertPosition);
                            backImg = document.getElementById("dp-popup").style.backgroundImage.replace("-u","-d");
                            $pop.css('background-image', backImg);
                        }
                    }
                    if (this.horizontalPosition == $.dpConst.POS_AUTO) {
                        if ((eleOffset.left + $ele.width() + $pop.width() + (calPadding * 3)) > viewportRightBorder) {
                            horizPosition = eleOffset.left - $pop.width();
                            horizPosition = horizPosition - (calPadding * 2);
                            $pop.css('left', horizPosition);
                            backImg = document.getElementById("dp-popup").style.backgroundImage.replace("l.","r.");
                            $pop.css('background-image', backImg);

                        }
                    }
                    if (this.verticalPosition == $.dpConst.POS_BOTTOM) {
                        $pop.css('top', eleOffset.top + $ele.height() - $pop.height() + c.verticalOffset);
                    }
                    if (this.horizontalPosition == $.dpConst.POS_RIGHT) {
                        $pop.css('left', eleOffset.left + $ele.width() - $pop.width() + c.horizontalOffset);
                    }
                    //					$('.selectee', this.context).focus();
                    $(document).bind('mousedown.datepicker', this._checkMouse);
                }
				
            },
            setRenderCallback : function(a)
            {
                if (a == null) return;
                if (a && typeof(a) == 'function') {
                    a = [a];
                }
                this.renderCallback = this.renderCallback.concat(a);
            },
            cellRender : function ($td, thisDate, month, year) {
                var c = this.dpController;
                var d = new Date(thisDate.getTime());
				
                // add our click handlers to deal with it when the days are clicked...
				
                $td.bind(
                    'click',
                    function()
                    {
                        var $this = $(this);
                        if (!$this.is('.disabled')) {
                            c.setSelected(d, !$this.is('.selected') || !c.selectMultiple, false, true);
                            if (c.closeOnSelect) {
                                c._closeCalendar();
                            }
                            // TODO: Instead of this which doesn't work in IE anyway we should find the next focusable element in the document
                            // and pass the focus onto that. That would allow the user to continue on the form as expected...
                            if (!$.browser.msie)
                            {
                                $(c.ele).trigger('focus', [$.dpConst.DP_INTERNAL_FOCUS]);
                            }
                        }
                    }
                    );
				
                if (c.isSelected(d)) {
                    $td.addClass('selected');
                    if (c.settings.selectWeek)
                    {
                        $td.parent().addClass('selectedWeek');
                    }
                } else  if (c.selectMultiple && c.numSelected == c.numSelectable) {
                    $td.addClass('unselectable');
                }
				
            },
            _applyRenderCallbacks : function()
            {
                var c = this;
                $('td', this.context).each(
                    function()
                    {
                        for (var i=0; i<c.renderCallback.length; i++) {
                            $td = $(this);
                            c.renderCallback[i].apply(this, [$td, Date.fromString($td.data('datePickerDate')), c.displayedMonth, c.displayedYear]);
                        }
                    }
                    );
                return;
            },
            // ele is the clicked button - only proceed if it doesn't have the class disabled...
            // m and y are -1, 0 or 1 depending which direction we want to go in...
            _displayNewMonth : function(ele, m, y) 
            {
                if (!$(ele).is('.disabled')) {
                    this.setDisplayedMonth(this.displayedMonth + m, this.displayedYear + y, true);
                }
                ele.blur();
                return false;
            },
            _rerenderCalendar : function()
            {
                this._clearCalendar();
                this._renderCalendar();
            },
            _renderCalendar : function()
            {
                // set the title...
                $('h2', this.context).html((new Date(this.displayedYear, this.displayedMonth, 1)).asString($.dpText.HEADER_FORMAT));
				
                // render the calendar...
                $('.dp-calendar', this.context).renderCalendar(
                    $.extend(
                    {},
                        this.settings, 
                        {
                            month			: this.displayedMonth,
                            year			: this.displayedYear,
                            renderCallback	: this.cellRender,
                            dpController	: this,
                            hoverClass		: this.hoverClass
                        })
                    );
				
                // update the status of the control buttons and disable dates before startDate or after endDate...
                // TODO: When should the year buttons be disabled? When you can't go forward a whole year from where you are or is that annoying?
                if (this.displayedYear == this.startDate.getFullYear() && this.displayedMonth == this.startDate.getMonth()) {
                    $('.dp-nav-prev-year', this.context).addClass('disabled');
                    $('.dp-nav-prev-month', this.context).addClass('disabled');
                    $('.dp-calendar td.other-month', this.context).each(
                        function()
                        {
                            var $this = $(this);
                            if (Number($this.text()) > 20) {
                                $this.addClass('disabled');
                            }
                        }
                        );
                    var d = this.startDate.getDate();
                    $('.dp-calendar td.current-month', this.context).each(
                        function()
                        {
                            var $this = $(this);
                            if (Number($this.text()) < d) {
                                $this.addClass('disabled');
                            }
                        }
                        );
                } else {
                    $('.dp-nav-prev-year', this.context).removeClass('disabled');
                    $('.dp-nav-prev-month', this.context).removeClass('disabled');
                    var d = this.startDate.getDate();
                    if (d > 20) {
                        // check if the startDate is last month as we might need to add some disabled classes...
                        var st = this.startDate.getTime();
                        var sd = new Date(st);
                        sd.addMonths(1);
                        if (this.displayedYear == sd.getFullYear() && this.displayedMonth == sd.getMonth()) {
                            $('.dp-calendar td.other-month', this.context).each(
                                function()
                                {
                                    var $this = $(this);
                                    if (Date.fromString($this.data('datePickerDate')).getTime() < st) {
                                        $this.addClass('disabled');
                                    }
                                }
                                );
                        }
                    }
                }
                if (this.displayedYear == this.endDate.getFullYear() && this.displayedMonth == this.endDate.getMonth()) {
                    $('.dp-nav-next-year', this.context).addClass('disabled');
                    $('.dp-nav-next-month', this.context).addClass('disabled');
                    $('.dp-calendar td.other-month', this.context).each(
                        function()
                        {
                            var $this = $(this);
                            if (Number($this.text()) < 14) {
                                $this.addClass('disabled');
                            }
                        }
                        );
                    var d = this.endDate.getDate();
                    $('.dp-calendar td.current-month', this.context).each(
                        function()
                        {
                            var $this = $(this);
                            if (Number($this.text()) > d) {
                                $this.addClass('disabled');
                            }
                        }
                        );
                } else {
                    $('.dp-nav-next-year', this.context).removeClass('disabled');
                    $('.dp-nav-next-month', this.context).removeClass('disabled');
                    var d = this.endDate.getDate();
                    if (d < 13) {
                        // check if the endDate is next month as we might need to add some disabled classes...
                        var ed = new Date(this.endDate.getTime());
                        ed.addMonths(-1);
                        if (this.displayedYear == ed.getFullYear() && this.displayedMonth == ed.getMonth()) {
                            $('.dp-calendar td.other-month', this.context).each(
                                function()
                                {
                                    var $this = $(this);
                                    if (Number($this.text()) > d) {
                                        $this.addClass('disabled');
                                    }
                                }
                                );
                        }
                    }
                }
                this._applyRenderCallbacks();
            },
            _closeCalendar : function(programatic, ele)
            {
                if (!ele || ele == this.ele)
                {
                    $(document).unbind('mousedown.datepicker');
                    $(document).unbind('keydown.datepicker');
                    this._clearCalendar();
                    $('#dp-popup a').unbind();
                    $('#dp-popup').empty().remove();
                    if (!programatic) {
                        $(this.ele).trigger('dpClosed', [this.getSelected()]);
                    }
                }
            },
            // empties the current dp-calendar div and makes sure that all events are unbound
            // and expandos removed to avoid memory leaks...
            _clearCalendar : function()
            {
                // TODO.
                $('.dp-calendar td', this.context).unbind();
                $('.dp-calendar', this.context).empty();
            }
        }
        );
	
    // static constants
    $.dpConst = {
        SHOW_HEADER_NONE	:	0,
        SHOW_HEADER_SHORT	:	1,
        SHOW_HEADER_LONG	:	2,
        POS_TOP				:	0,
        POS_BOTTOM			:	1,
        POS_LEFT			:	0,
        POS_RIGHT			:	1,
        POS_AUTO            :   0,
        DP_INTERNAL_FOCUS	:	'dpInternalFocusTrigger'
    };
    // localisable text
    $.dpText = {
        TEXT_PREV_YEAR		:	'Año anterior',
        TEXT_PREV_MONTH		:	'Mes anterior',
        TEXT_NEXT_YEAR		:	'Año siguiente',
        TEXT_NEXT_MONTH		:	'Mes siguiente',
        TEXT_CLOSE				:	'Cerrar',
        TEXT_CHOOSE_DATE	:	'Seleccionar fecha',
        HEADER_FORMAT		:	'mmmm yyyy'
    };
    // version
    $.dpVersion = '$Id: jquery.datePicker.js 70 2009-04-05 19:25:15Z kelvin.luck $';

    $.fn.datePicker.defaults = {
        month				: undefined,
        year				: undefined,
        showHeader			: $.dpConst.SHOW_HEADER_SHORT,
        startDate			: undefined,
        endDate				: undefined,
        inline				: false,
        renderCallback		: null,
        createButton		: true,
        showYearNavigation	: false,
        closeOnSelect		: true,
        displayClose		: true,
        selectMultiple		: false,
        numSelectable		: Number.MAX_VALUE,
        clickInput			: false,
        rememberViewedMonth	: true,
        selectWeek			: false,
        verticalPosition	: $.dpConst.POS_TOP,
        horizontalPosition	: $.dpConst.POS_LEFT,
        verticalOffset		: 0,
        horizontalOffset	: 0,
        hoverClass			: 'dp-hover'
    };

    function _getController(ele)
    {
        if (ele._dpId) return $.event._dpCache[ele._dpId];
        return false;
    };
	
    // make it so that no error is thrown if bgIframe plugin isn't included (allows you to use conditional
    // comments to only include bgIframe where it is needed in IE without breaking this plugin).
    if ($.fn.bgIframe == undefined) {
        $.fn.bgIframe = function() {
            return this; 
        };
    };


    // clean-up
    $(window)
    .bind('unload', function() {
        var els = $.event._dpCache || [];
        for (var i in els) {
            $(els[i].ele)._dpDestroy();
        }
    });
		
        function getStyle(el, cssprop)
        {
            if (el.currentStyle) //IE
                return el.currentStyle[cssprop];
            else if (document.defaultView && document.defaultView.getComputedStyle) //Firefox
                return document.defaultView.getComputedStyle(el, "")[cssprop];
            else //try and get inline style
                return el.style[cssprop];
        }



})(jQuery);

function sumaDias(fecha, diasSumar){
	fecha.setTime(fecha.getTime()+ parseInt(diasSumar *24*60*60*1000)); 
	return fecha; 
}

function updatePartner(input, date){
	if (input.id.substring(input.id.indexOf('-')+1,input.id.length) == 'Inicio'){
		document.getElementById(input.id.substring(0,input.id.indexOf('-')) + "Inicio").value = date.asString();
		var finDate = sumaDias(date, 1).asString();
		document.getElementById(input.id.substring(0,input.id.indexOf('-')) + "-Fin").value = finDate;
		document.getElementById(input.id.substring(0,input.id.indexOf('-')) + "Fin").value = finDate;
			
	}else{
		document.getElementById(input.id.substring(0,input.id.indexOf('-')) + "Fin").value = date.asString();	
	}
}

Date.dayNames = ['Domingo', 'Lunes', 'Martes', 'Miercoles', 'Jueves', 'Viernes', 'Sabado'];
Date.abbrDayNames = ['Dom', 'Lun', 'Mar', 'Mie', 'Jue', 'Vie', 'Sab'];
Date.monthNames = ['Enero', 'Febrero', 'Marzo', 'Abril', 'Mayo', 'Junio', 'Julio', 'Agosto', 'Septiembre', 'Octubre', 'Noviembre', 'Diciembre'];
Date.abbrMonthNames = ['Ene', 'Feb', 'Mar', 'Abr', 'May', 'Jun', 'Jul', 'Ago', 'Sep', 'Oct', 'Nov', 'Dic'];
Date.firstDayOfWeek = 7;
Date.format = 'dd/mm/yyyy';
Date.fullYearStart = '20';

(function() {function add(name, method) {if( !Date.prototype[name] ) {Date.prototype[name] = method;}};add("isLeapYear", function() {var y = this.getFullYear();return (y%4==0 && y%100!=0) || y%400==0;});add("isWeekend", function() {return this.getDay()==0 || this.getDay()==6;});add("isWeekDay", function() {return !this.isWeekend();});add("getDaysInMonth", function() {return [31,(this.isLeapYear() ? 29:28),31,30,31,30,31,31,30,31,30,31][this.getMonth()];});add("getDayName", function(abbreviated) {return abbreviated ? Date.abbrDayNames[this.getDay()] : Date.dayNames[this.getDay()];});add("getMonthName", function(abbreviated) {return abbreviated ? Date.abbrMonthNames[this.getMonth()] : Date.monthNames[this.getMonth()];});add("getDayOfYear", function() {var tmpdtm = new Date("1/1/" + this.getFullYear());return Math.floor((this.getTime() - tmpdtm.getTime()) / 86400000);});add("getWeekOfYear", function() {return Math.ceil(this.getDayOfYear() / 7);});add("setDayOfYear", function(day) {this.setMonth(0);this.setDate(day);return this;});add("addYears", function(num) {this.setFullYear(this.getFullYear() + num);return this;});add("addMonths", function(num) {var tmpdtm = this.getDate();this.setMonth(this.getMonth() + num);if (tmpdtm > this.getDate())this.addDays(-this.getDate());return this;});add("addDays", function(num) {this.setDate(this.getDate() + num);return this;});add("addHours", function(num) {this.setHours(this.getHours() + num);return this;});add("addMinutes", function(num) {this.setMinutes(this.getMinutes() + num);return this;});add("addSeconds", function(num) {this.setSeconds(this.getSeconds() + num);return this;});add("zeroTime", function() {this.setMilliseconds(0);this.setSeconds(0);this.setMinutes(0);this.setHours(0);return this;});add("asString", function(format) {var r = format || Date.format;return r.split('yyyy').join(this.getFullYear()).split('yy').join((this.getFullYear() + '').substring(2)).split('mmmm').join(this.getMonthName(false)).split('mmm').join(this.getMonthName(true)).split('mm').join(_zeroPad(this.getMonth()+1)).split('dd').join(_zeroPad(this.getDate()));});Date.fromString = function(s){var f = Date.format;var d = new Date('01/01/1977');var mLength = 0;var iM = f.indexOf('mmmm');if (iM > -1) {for (var i=0; i<Date.monthNames.length; i++) {var mStr = s.substr(iM, Date.monthNames[i].length);if (Date.monthNames[i] == mStr) {mLength = Date.monthNames[i].length - 4;break;}}d.setMonth(i);} else {iM = f.indexOf('mmm');if (iM > -1) {var mStr = s.substr(iM, 3);for (var i=0; i<Date.abbrMonthNames.length; i++) {if (Date.abbrMonthNames[i] == mStr) break;}d.setMonth(i);} else {d.setMonth(Number(s.substr(f.indexOf('mm'), 2)) - 1);}}var iY = f.indexOf('yyyy');if (iY > -1) {if (iM < iY){iY += mLength;}d.setFullYear(Number(s.substr(iY, 4)));} else {if (iM < iY){iY += mLength;}d.setFullYear(Number(Date.fullYearStart + s.substr(f.indexOf('yy'), 2)));}var iD = f.indexOf('dd');if (iM < iD){iD += mLength;}d.setDate(Number(s.substr(iD, 2)));if (isNaN(d.getTime())) {return false;}return d;};var _zeroPad = function(num) {var s = '0'+num;return s.substring(s.length-2)};})();

(function($){    $.fn.extend({datePickerMultiMonth : function(s){s.numMonths = s.numMonths || 2;$(this).each(function(){var dps = $.extend({}, $.fn.datePicker.defaults, s);var $dpmm = $(this);var pickers = [];var basePicker;var m;if (s.inline) {$dpmm.html('');for (var i=0; i<s.numMonths; i++){(function(i) {var first = i == 0;var last = i == s.numMonths - 1;var $date =  $('<div />').datePicker(dps).bind('dpMonthChanged',function(event, displayedMonth, displayedYear){if (first) {$dpmm.trigger('dpMonthChanged', [displayedMonth, displayedYear]);} else {pickers[i-1].dpSetDisplayedMonth(displayedMonth-1, displayedYear);}if (!last){pickers[i+1].dpSetDisplayedMonth(displayedMonth+1, displayedYear);}return false;}).bind('dateSelected',function(event, date, $td, status){if (first){$dpmm.trigger('dateSelected', [date, $td, status]);} else {pickers[i-1].dpSetSelected(date.asString(), status, false);}if (!last){pickers[i+1].dpSetSelected(date.asString(), status, false);}return false;});$date.find('.dp-nav-prev').css('display', first ? 'block' : 'none');$date.find('.dp-nav-next').css('display', last ? 'block' : 'none');pickers.push($date);$dpmm.append($date);})(i);}basePicker = pickers[0];} else {var displayedMonth;var displayedYear;var selectedDate;if (dps.closeOnSelect == false) throw new Error("Popup multi month date pickers must close on select");if (dps.selectMultiple == true) throw new Error("Popup multi month date pickers aren't compatible with selectMultiple");$dpmm.datePicker(dps).bind('dateSelected',function(event, date, $td, status){selectedDate = date.asString();}).bind('dpDisplayed',function(event, datePickerDiv){var $popup = $(datePickerDiv).empty();var d = $dpmm.dpGetSelected();if (d.length) {selectedDate = new Date(d[0]).asString();}for (var i=0; i<s.numMonths; i++) {(function(i) {var s = $.extend({}, dps);s.inline = true;s.month = displayedMonth + i;s.year = displayedYear;var last = i == s.numMonths-1;var first = i == 0;var $dp = $('<div />');$popup.append($dp);$dp.datePicker(s).bind('dpMonthChanged',function(event, newMonth, newYear){if (i == 0){displayedMonth = newMonth;displayedYear = newYear;}if (!first) {pickers[i-1].dpSetDisplayedMonth(newMonth-1, newYear);}if (!last){pickers[i+1].dpSetDisplayedMonth(newMonth+1, newYear);}return false;}).bind('dateSelected',function(event, date, $td, status){var d = date.asString();if (d != selectedDate) {basePicker.dpSetSelected(date.asString());basePicker.dpClose();}}).find('.dp-nav-next').css('display', last ? 'block' : 'none').end() .find('.dp-nav-prev').css('display', first ? 'block' : 'none').end();if (selectedDate) {$dp.dpSetSelected(selectedDate, true, false);}pickers.push($dp);})(i);}}).bind('dpMonthChanged',function(event, newMonth, newYear){displayedMonth = newMonth;displayedYear = newYear;}).bind('dpClosed',function(event, selected){pickers = [];});basePicker = $dpmm;}$dpmm.data('dpBasePicker', basePicker);basePicker.dpSetDisplayedMonth(1, 3000);basePicker.dpSetDisplayedMonth(Number(s.month), Number(s.year));});return this;},dpmmGetSelected : function(){var basePicker = $(this).data('dpBasePicker');return basePicker.dpGetSelected();}});})(jQuery);
