function readLinked(datePicker, date)
{
    datePicker.val(date.val()); 
    return {}; 
}
 
function updateLinked(year, month, day, date, newDate)
{ 
    date.val(newDate);
    year.val(newDate.substring(0, 4));
    month.val(newDate.substring(5, 7));
    day.val(newDate.substring(8, 10));
} 

function fillDays(dayCtrl, from, to, val)
{
    dayCtrl.empty();
    for (var i = from; i <= to; i++)
    {
        dayCtrl.append("<option value=\"" + ( i < 10 ? ("0" + i) : i ) + "\">" + i +  "</option>");
    }
    if ( typeof(val) != "undefined" )
    {
        dayCtrl.val(val);
    }
}

function fillMonths(monthCtrl, from, to, val)
{
    var months = [
        "", 
        "Январь","Февраль","Март","Апрель","Май","Июнь",
        "Июль","Август","Сентябрь","Октябрь","Ноябрь","Декабрь"
    ];
    monthCtrl.empty();
    for (var i = from; i <= to && i < months.length; i++)
    {
        monthCtrl.append("<option value=\"" + ( i < 10 ? ("0" + i) : i ) + "\">" + months[i] +  "</option>");
    }
    if ( typeof(val) != "undefined" )
    {
        monthCtrl.val(val);
    }
}

function fillYears(yearCtrl, from, to, val)
{
    yearCtrl.empty();
    for (var i = from; i <= to; i++)
    {
        yearCtrl.append("<option value=\"" + i + "\">" + i +  "</option>");
    }
    if ( typeof(val) != "undefined" )
    {
        if ( val > to )
        {
            yearCtrl.val(to);
        }
        else if ( val < from )
        {
            yearCtrl.val(from);
        }
        else
        {
            yearCtrl.val(val);
        }
    }
}

function checkLinkedDays(year, month, day)
{ 
    var daysInMonth = 32 - new Date(year.val(), month.val() - 1, 32).getDate(); 
    var dayVal = day.val();
    fillDays(day, 1, daysInMonth);
    if ( dayVal > daysInMonth )
    {
        day.val(daysInMonth); 
    }
    else
    {
        day.val(dayVal);
    }
}

function fixDateRange(startYear, startMonth, startDay, endYear, endMonth, endDay, oEndDate)
{
    var startDate  = new Date(startYear.val(), startMonth.val(), startDay.val());
		var endDate    = new Date(endYear.val(), endMonth.val(), endDay.val());
    
    if ( startDate > endDate )
    {
        endYear.val(startYear.val());
        endMonth.val(startMonth.val());
        endDay.val(startDay.val());
        oEndDate.val(startYear.val() + "-" + startMonth.val() + "-" + startDay.val());
    }
}

function limitEndDate(startYear, startMonth, startDay, endYear, endMonth, endDay)
{
    var startDate  = new Date(startYear.val(), startMonth.val(), startDay.val());

    fillYears(endYear, startYear.val(), YEAR_TO, endYear.val());
    if ( endYear.val() > startYear.val() )
    {
        fillMonths(endMonth, 1, 12, endMonth.val());
    }
    else
    {
        fillMonths(endMonth, parseInt(startMonth.val(), 10), 12, endMonth.val());
    }
    var daysInMonth = 32 - new Date(endYear.val(), endMonth.val() - 1, 32).getDate(); 
    if ( endYear.val() > startYear.val() || (endYear.val() == startYear.val() && endMonth.val() > startMonth.val()) )
    {
        fillDays(endDay, 1, daysInMonth, endDay.val());
    }
    else
    {
        fillDays(endDay, parseInt(startDay.val(), 10), daysInMonth, endDay.val());
    }
}

function initDateControl(startYear, startMonth, startDay, startDate, startDatePicker)
{
    YEAR_FROM = new Date().getFullYear() - 5;
    YEAR_TO   = new Date().getFullYear() + 10;

    var d = new Date();
    var year  = d.getFullYear();
    var month = d.getMonth() + 1;
    var day   = d.getDate();
    
    month = month < 10 ? ("0" + month) : month;
    day = day < 10 ? ("0" + day) : day;
    
    if ( startDate.val() == "" )
    {
        startDate.val(year + "-" + month + "-" + day);
    }

    if ( startDatePicker )
    {
        $(startDatePicker).datepicker({ 
            minDate: new Date(YEAR_FROM, 0, 1),
            maxDate: new Date(YEAR_TO, 12 - 1, 31),
            beforeShow: $.bind(null, readLinked, startDatePicker, startDate),
            onSelect: function (date) {
                updateLinked(startYear, startMonth, startDay, startDate, date);
            },
            showOn: "both",
            buttonImageOnly: false,
            dateFormat: "yy-mm-dd"
        }); 
    }

    $([startMonth, startYear]).each( function () 
        {
            $(this).bind("change", $.bind(null, checkLinkedDays, startYear, startMonth, startDay));
        }
    );
    
    $([startMonth, startYear, startDay]).each( function () 
        {
            $(this).bind("change", function() {
                    startDate.val(startYear.val() + "-" + startMonth.val() + "-" + startDay.val());
                }
            );
        }
    );
    updateLinked(startYear, startMonth, startDay, startDate, startDate.val());
    checkLinkedDays(startYear, startMonth, startDay);
}

function initDateRange(startYear, startMonth, startDay, startDate, startDatePicker,
                       endYear, endMonth, endDay, endDate, endDatePicker)
{
    YEAR_FROM = new Date().getFullYear() - 5;
    YEAR_TO   = new Date().getFullYear() + 10;
    
    var d = new Date();
    var year  = d.getFullYear();
    var month = d.getMonth() + 1;
    var day   = d.getDate();
    month = month < 10 ? ("0" + month) : month;
    day = day < 10 ? ("0" + day) : day;
    
    if ( startDate.val() == "" )
    {
        startDate.val(year + "-" + month + "-" + day);
    }
    if ( endDate.val() == "" )
    {
        endDate.val(year + "-" + month + "-" + day);
    }
    
    $(startDatePicker).datepicker({ 
        minDate: new Date(YEAR_FROM, 0, 1),
        maxDate: new Date(YEAR_TO, 12 - 1, 31),
        beforeShow: $.bind(null, readLinked, startDatePicker, startDate),
        onSelect: function (date) {
            updateLinked(startYear, startMonth, startDay, startDate, date);
            fixDateRange(startYear, startMonth, startDay, endYear, endMonth, endDay, endDate);
            limitEndDate(startYear, startMonth, startDay, endYear, endMonth, endDay);
        },
        showOn: "both",
        buttonImageOnly: false,
        dateFormat: "yy-mm-dd"
    }); 
    
    $([startMonth,startYear]).each( function () 
        {
            $(this).bind("change", $.bind(null, checkLinkedDays, startYear, startMonth, startDay));
        }
    );
    
    $([startMonth, startYear, startDay]).each( function () 
        {
            $(this).bind("change", function() {
                    startDate.val(startYear.val() + "-" + startMonth.val() + "-" + startDay.val());
                    fixDateRange(startYear, startMonth, startDay, endYear, endMonth, endDay, endDate);
                    limitEndDate(startYear, startMonth, startDay, endYear, endMonth, endDay);
                }
            );
        }
    );

    $(endDatePicker).datepicker({ 
        minDate: new Date(YEAR_FROM, 0, 1),
        maxDate: new Date(YEAR_TO, 12 - 1, 31),
        beforeShow: function () {
            readLinked(endDatePicker, endDate);
        },
        beforeShowDay: function (date) {
            var opt = [1, "", ""];
            var dstr = startDate.val();
            sd = new Date(dstr.substring(0, 4), dstr.substring(5, 7)-1, dstr.substring(8, 10));
            if ( date < sd )
            {
                opt[0] = 0;
            }
            return opt;
        },
        onSelect: function (date) {
            $("option", endYear).show().removeAttr("disabled");
            $("option", endMonth).show().removeAttr("disabled");
            $("option", endDay).show().removeAttr("disabled");
            updateLinked(endYear, endMonth, endDay, endDate, date);
            fixDateRange(startYear, startMonth, startDay, endYear, endMonth, endDay, endDate);
            limitEndDate(startYear, startMonth, startDay, endYear, endMonth, endDay);
        },
        showOn: "both",
        buttonImageOnly: false,
        dateFormat: "yy-mm-dd"
    });
    $([endMonth, endYear]).each( function () 
        {
            $(this)
                .bind("change", $.bind(null, checkLinkedDays, endYear, endMonth, endDay, endDate))
                .bind("change", $.bind(null, fixDateRange, startYear, startMonth, startDay, endYear, endMonth, endDay, endDate))
                .bind("change", $.bind(null, limitEndDate, startYear, startMonth, startDay, endYear, endMonth, endDay));
        }
    );
    
    $([endMonth, endYear, endDay]).each( function ()
        {
            $(this).bind("change", function() {
                    endDate.val(endYear.val() + "-" + endMonth.val() + "-" + endDay.val());
                }
            );
        }
    )

    updateLinked(startYear, startMonth, startDay, startDate, startDate.val());
    updateLinked(endYear,   endMonth,   endDay,   endDate,   endDate.val());
    checkLinkedDays(startYear, startMonth, startDay);
    checkLinkedDays(endYear, endMonth, endDay);
    limitEndDate(startYear, startMonth, startDay, endYear, endMonth, endDay);
    endDate.val(endYear.val() + "-" + endMonth.val() + "-" + endDay.val());
}
