//      $RCSfile: advanced_search.js,v $ $Revision: 1.12 $
//----------------------------------------------------------------------
// Utility values and methods for Dates
//----------------------------------------------------------------------
Date.MS_PER_DAY = 86400000;
var monthNames = [ 'Month', 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
                            'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec' ];

var minDate = new Date(Date.UTC(1954,7,16,12,0,0,000));
var minYear = minDate.getUTCFullYear();
var minMonth = minDate.getUTCMonth() + 1;
var minDay = minDate.getUTCDate();
var maxDate = new Date(new Date().getTime() + 604800000);
var maxYear = maxDate.getUTCFullYear();
var maxMonth = maxDate.getUTCMonth();
var searchForm;
var dateForm;
var issueForm;
var nonMondays = new Object;
var not26issues = new Object;
var maxVol;

// make sure we have good array stuff
if (!Array.prototype.push)
{
    Array.prototype.push = function () 
    {
        for (var i=0; i<arguments.length; ++i)
        {
            this[this.length++] = arguments[i];
        }
    }
}

function initForm(newMaxVol, newNonMondays, newOddVolumes)
{
    searchForm = document.searchForm;
    dateForm = document.dateForm;
    issueForm = document.issueForm;
    maxVol = newMaxVol;
    
    //searchForm.minYear.options.length = 1;
    //searchForm.maxYear.options.length = 1;
    dateForm.exactYear.options.length = 1;
    for (var year=maxYear; year >= minYear; --year)
    {
    //    searchForm.minYear.options[searchForm.minYear.options.length] 
    //        = new Option(year, year, false, false);
    //    searchForm.maxYear.options[searchForm.maxYear.options.length] 
    //        = new Option(year, year, false, false);
        dateForm.exactYear.options[dateForm.exactYear.options.length] 
            = new Option(year, year, false, false);
    }

    //changedYear(searchForm.minYear);
    //changedYear(searchForm.maxYear);
    changedYear(dateForm.exactYear);

    for (var vol=1; vol <= maxVol; ++vol)
    {
        issueForm.volume.options[issueForm.volume.options.length] 
            = new Option(vol, vol, false, false);
    }
    changedVol(issueForm.volume);
    setNonMondays(newNonMondays);
    setOddVolumes(newOddVolumes);
}

function changedYear(yearElement)
{
    var monthElement;
    var startIndex = 1;

    if (yearElement == searchForm.minYear)
    {
        monthElement = searchForm.minMonth;
    }
    else if (yearElement == searchForm.maxYear)
    {
        monthElement = searchForm.maxMonth;
    }
    else if (yearElement == dateForm.exactYear)
    {
        monthElement = dateForm.exactMonth;
    }
    else
    {
        alert("unrecognized form element");
        return;
    }
        
    var chosenMonth;
    if (monthElement.selectedIndex >= startIndex)
        chosenMonth = monthElement.options[monthElement.selectedIndex].value;
    var chosenYear =
        yearElement.options[yearElement.selectedIndex].value;

    var startMonth = 1, endMonth = monthNames.length - 1;

    if (chosenYear == minYear)
    {
        startMonth = minMonth;
    }
    else if (chosenYear == maxYear)
    {
        endMonth = maxMonth + 1;
    }

    monthElement.options.length = startIndex;
    var chosenIndex;
    for (var i=startMonth; i<=endMonth; ++i)
    {
        var opt = new Option(monthNames[i], i, false, false);
        if (i == chosenMonth)
            chosenIndex = monthElement.options.length;
        monthElement.options[monthElement.options.length]  = opt;
    }
    monthElement.selectedIndex = chosenIndex;

    changedMonth(monthElement);
}

function changedMonth(monthElement)
{
    if (monthElement != dateForm.exactMonth)
        return;

    var dayElement = dateForm.exactDay;
    var yearElement = dateForm.exactYear;
    var chosenYear =
        yearElement.options[yearElement.selectedIndex].value;

    var month = 
       monthElement.options[monthElement.selectedIndex].value
    var date = new Date();
    var issues = [];

    if (chosenYear)
    {
        date.setUTCFullYear(chosenYear);
    }
    else 
    {
        // default to random year - but a leap year so Feb 29 is an option
        date.setUTCFullYear(2000);
    }


    // default to 31-day month for similar reason
    if (!month)
        month = 1;
    
    // then subtract 1 to get from the 1-12 mapping to JS internal 0-11 mapping
    month -= 1

    date.setUTCMonth(month, 1);
    date.setUTCHours(12);

    var issues = [];
    var increment = Date.MS_PER_DAY;   // one day's worth of milliseconds
    while (date.getTime() < minDate.getTime())
    {
        date.setTime(date.getTime() + increment);
    }

    if (chosenYear)
    {
        while (date.getUTCDay() != 1)
        {
            date.setTime(date.getTime() + increment);
        }
        increment *= 7; // use only Mondays if we have a specific year
    }

    while (date.getUTCMonth() == month && date.getTime() <= maxDate.getTime())
    {
        issues.push(date.getUTCDate());
        date.setTime(date.getTime() + increment);
    }
    
    if (chosenYear && nonMondays[chosenYear] && nonMondays[chosenYear][month])
    {
        issues = issues.concat(nonMondays[chosenYear][month]).sort(
                function (a, b) { return a - b; } );
    }

    dayElement.options.length = 1;
    for (var i = 0; i < issues.length; ++i)
    {
        dayElement.options[dayElement.options.length] =
            new Option(issues[i], issues[i], false, false);
    }
}

function changedVol(volElement)
{
    var issueElement;

    if (volElement == issueForm.volume)
    {
        issueElement = issueForm.issue;
    }
    else
    {
        return;
    }
        
    var chosenVolume, chosenIssue;

    if (volElement.selectedIndex >= 0)
    {
        chosenVolume =  volElement.options[volElement.selectedIndex].value
    }

    if (issueElement.selectedIndex > 0)
        chosenIssue = issueElement.selectedIndex;

    var lastIssue = 26;

    if (chosenVolume && not26issues[chosenVolume])
    {
        lastIssue = not26issues[chosenVolume];
    }

    issueElement.options.length = 1;
    for (var i = 1; i <= lastIssue; ++i)
    {
        issueElement.options[issueElement.options.length] =
            new Option(i, i, false, false);
    }
    issueElement.selectedIndex = chosenIssue;
}

// given an array of time values (milliseconds since 
// UTC 1970-01-01 00:00:00.000), populate the nonMondays object
// with (year[month] => [days]) entries
function setNonMondays(list)
{
    for (var i=0; i<list.length; ++i)
    {
        var date = new Date(list[i]);
        date.setUTCHours(12);
        var year = date.getUTCFullYear();
        var month = date.getUTCMonth();
        var day = date.getUTCDate();
        if (!nonMondays[year])
            nonMondays[year] = new Array();
        if (!nonMondays[year][month])
            nonMondays[year][month] = new Array();
        nonMondays[year][month].push(day);
    }
}

// set the not26issues object to an array of (volume, issue count) pairs
function setOddVolumes(list)
{
    for (var i=0; i<list.length; ++i)
    {
        var pair = list[i];
        not26issues[pair[0]] = pair[1];
    }
}

function checkSearchForm()
{
    var minM = searchForm.minMonth;
    var minY = searchForm.minYear;
    var maxM = searchForm.maxMonth;
    var maxY = searchForm.maxYear;

    if (minM.selectedIndex && !minY.selectedIndex)
    {
        alert("You need to select a year as well as a month.");
        minY.focus();
        return false;
    }

    if (maxM.selectedIndex && !maxY.selectedIndex)
    {
        alert("You need to select a year as well as a month.");
        maxY.focus();
        return false;
    }
    return true;
}
