var monthNames = "January February March April May June July August September October November December".split(" ");
var maxDays = new Array(31,28,31,30,31,30,31,31,30,31,30,31);
var weekdayNames = "Sunday Monday Tuesday Wednesday Thursday Friday Saturday".split(" ");


/*****************************************************************************************/
/// DateSelector
/*****************************************************************************************/
function DateSelector(instance){
    return "<ul>" + ParseAsPartialDate(instance.getToken()).join('') + "</ul>"; 
}


/*****************************************************************************************/
/// addLoadEvent
/*****************************************************************************************/
function addLoadEvent(func) {
 var oldonload = window.onload;
 if (typeof window.onload != 'function') {
  window.onload = func;
 } else {
  window.onload = function() {
   oldonload();
   func();
  }
 }
}

function completeDate(event)
{
    var element = Event.element(event);
	var dates = ParseAsPartialDate(element.value);
	var date = "";
	if(dates.length > 0)
	    date = dates[0];
	    
	date = date.replace("<li>", "");
	date = date.replace("</li>", "");
	element.value = date;
}

// create a global function so that it can be placed anywhere
function removeZeros(yourString){
    // do nothing if the input is already zero or if there are no leading zeros
    if (typeof yourString == "string" && yourString.charAt(0) != "0"){
        ret = yourString;
    } else if (yourString == 0) {
        ret = yourString;
    } else {
        // If the first character in the input is zero, then remove it. Repeat until the first character is not zero
        for(i=0; i<=yourString.length-1; i++) { 
            if (yourString.charAt(i) == "0") { 
                ret = yourString.slice(i+1);
            } else {
                break;
            }
        }
    }
    // return the number for further calculations or so that it can be displayed 
    return(Number(ret));
}

/*****************************************************************************************/
/// ParseAsPartialDate
// Custom Selector: return a list of dates matching the input string
/*****************************************************************************************/
function ParseAsPartialDate(DateString){
    var date = new Date();
    
    var currentDayPart = date.getDate();
    var currentMonthPart = monthNames[date.getMonth()];
    var currentYearPart = date.getFullYear();
    
    var dates = [];
    
    // TODO: What's with the double replace? -AB
    DateString = DateString.replace('-', ' ').replace('-', ' ');
    DateString = DateString.replace('\/', ' ').replace('\/', ' ');
    DateString = DateString.replace('\\', ' ').replace('\\', ' ');
    DateString = DateString.replace('.', ' ').replace('.', ' ');
    DateString = DateString.trim();
    while (DateString.indexOf('  ')!=-1){
          DateString = DateString.replace('  ', ' ');
    }
    
    var testDate = DateString.split(' ');

    // Specific Days 
    dates = AddRelativeDate(dates, DateString, "today", 0);
    dates = AddRelativeDate(dates, DateString, "tomorrow", 1);
    dates = AddRelativeDate(dates, DateString, "yesterday", -1);
    dates = AddRelativeDate(dates, DateString, "last week", -7);
    dates = AddRelativeDate(dates, DateString, "next week", 7);

    // Date spans
    if (parseInt(testDate[0]).toString()=='NaN')
    {
        var matchingWeekdays = stringIsWeekday(testDate[0])
    
        for (i=0;i<matchingWeekdays.length;i++) 
        {
            dates = AddRelativeOffsetDate(dates, matchingWeekdays[i], DateString, "this week", 0);
            dates = AddRelativeOffsetDate(dates, matchingWeekdays[i], DateString, "last week", -7);
            dates = AddRelativeOffsetDate(dates, matchingWeekdays[i], DateString, "next week", 7);
        }
    }
    
    // Standard Dates

    // Get date using one field
    if(testDate.length==1){
        if(parseInt(removeZeros(testDate[0]))>0){

            
            // ADD AS DAY
            if (parseInt(testDate[0]) <= maxDays[date.getMonth()]){
                dates = dates.concat("<li>" + parseInt(removeZeros(testDate[0])) + ' ' + currentMonthPart.substring(0,3) + ' ' + currentYearPart + "</li>");
            }
            
            // ADD AS MONTH
            if (parseInt(removeZeros(testDate[0]))<13){
                var monthPart = monthNames[parseInt(removeZeros(testDate[0]))-1];
      
                dates = dates.concat("<li>" + currentDayPart + ' ' + monthPart.substring(0,3) + ' ' + currentYearPart + "</li>");
            }
            
        }
        else{
            // ADD MATCHING AS MONTH     
            var matchingMonths = stringIsMonth(testDate[0])
    
            for (i=0;i<matchingMonths.length;i++) 
            {
                var monthPart = matchingMonths[i];

                dates = dates.concat("<li>" + currentDayPart + ' ' + monthPart.substring(0,3) + ' ' + currentYearPart + "</li>");
            }       
        }
    }
    // Get date from 2 fields
    else if(testDate.length>=2){
        var year = currentYearPart;

        if (testDate[2]!=null && parseInt(removeZeros(testDate[2]))>-1){
            var dtt = new Date();
            
            var yearYada = testDate[2];
            
            if (yearYada.length<4){
                yearYada = 2000 + parseInt(removeZeros(testDate[2]));
            }
            
            dtt.setFullYear(yearYada);
            
            year = dtt.getFullYear();
        } else {
            /* No year was passed, infer year by the target month's relative position to today (BOSS #812) */
            var PREV_YEAR_MONTH_LIMIT = 6;  // Get current date minus 6 months
        
            // Get todays date
            var currentDate = new Date();
            
            // A date object for the date the user is trying to set
            var targetDate = new Date();
            targetDate.setDate(testDate[0]);
 
            if(isNaN(testDate[1])) {
                targetDate.setMonth(monthStringAsInt(testDate[1])); //Convert from "Oct" to 10
            } else {
                targetDate.setMonth(testDate[1] - 1);
            }
 
//            // Check day is valid
//            if (parseInt(testDate[0]) > maxDays[targetDate.getMonth()]){
//                //testDate[0] = ""+maxDays[targetDate.getMonth()];
//                //targetDate.setDate(testDate[0]);
//                dates = [];
//                return dates;
//            }
                       
            // Get the date 6 months ago
            var datePastBoundary = new Date();
            datePastBoundary.setMonth(currentDate.getMonth()-PREV_YEAR_MONTH_LIMIT);
            
            // Get the date in 6 months from now
            var dateFutureBoundary = new Date();
            dateFutureBoundary.setMonth(currentDate.getMonth()+PREV_YEAR_MONTH_LIMIT);
            
            // Date falls into previous year
            if(datePastBoundary.getFullYear() < currentDate.getFullYear()) {
                // 6 months prior to today is sometime last year
                if(targetDate.getMonth() >= datePastBoundary.getMonth()) {
                    year--;
                }
            }
            
            // Date falls into next year
            if(dateFutureBoundary.getFullYear() > currentDate.getFullYear()) {
                if(targetDate.getMonth() < dateFutureBoundary.getMonth()) {
                    year++;
                }
            }
        }
        
        var targetDate = new Date();
        targetDate.setDate(testDate[0]);
        var targetMonth = testDate[1];
        if(isNaN(targetMonth)) {
            //targetDate.setMonth(monthStringAsInt(testDate[1])); //Convert from "Oct" to 10
            targetMonth = monthStringAsInt(testDate[1]); 
        } else {
            //targetDate.setMonth(testDate[1] - 1);
            targetMonth = testDate[1] - 1; 
        }
        targetDate.setMonth(targetMonth);
        
        // Check month is valid
        if(targetDate.getMonth() != targetMonth){
            dates = [];
            return dates;
        }

        // Check day is valid
        if (parseInt(testDate[0]) > maxDays[targetDate.getMonth()]){
            //testDate[0] = ""+maxDays[targetDate.getMonth()];
            //targetDate.setDate(testDate[0]);
            dates = [];
            return dates;
        }
                
        if(parseInt(removeZeros(testDate[0]))>0 && parseInt(removeZeros(testDate[1]))>0){
        
          if ( (parseInt(removeZeros(testDate[1]))<13) && (testDate[0] <= maxDays[removeZeros(testDate[1])-1])){
                var monthPart = monthNames[parseInt(removeZeros(testDate[1]))-1];
                dates = dates.concat("<li>" + parseInt(removeZeros(testDate[0])) + ' ' + monthPart.substring(0,3) + ' ' + year + "</li>");
          }
        
          
          if ( (parseInt(removeZeros(testDate[0]))<13) && (testDate[1] <= maxDays[parseInt(removeZeros(testDate[0]))-1])){            
                var monthPart = monthNames[parseInt(removeZeros(testDate[0]))-1];          
                dates = dates.concat("<li>" + parseInt(removeZeros(testDate[1])) + ' ' + monthPart.substring(0,3) + ' ' + year + "</li>");
          }
          
        }
        else if(parseInt(removeZeros(testDate[0]))>0 && parseInt(removeZeros(testDate[1])).toString()=='NaN'){
            
            var month = testDate[1];
        
            // ADD MATCHING AS MONTH     
            var matchingMonths = stringIsMonth(testDate[1])
    
            for (i=0;i<matchingMonths.length;i++) 
            {
                var monthPart = matchingMonths[i];

                dates = dates.concat("<li>" + parseInt(removeZeros(testDate[0])) + ' ' + monthPart.substring(0,3) + ' ' + year + "</li>");
            }    
            
            
        }
        else if((testDate[1]=='' ||parseInt(removeZeros(testDate[1])).toString()!='NaN') && parseInt(removeZeros(testDate[0])).toString()=='NaN'){
            
            
            var day = currentDayPart;
            
            if (parseInt(testDate[1])>0)
                day = parseInt(removeZeros(testDate[1]))
            
            // ADD MATCHING AS MONTH     
            var matchingMonths = stringIsMonth(testDate[0])
    
            for (i=0;i<matchingMonths.length;i++) 
            {
                var monthPart = matchingMonths[i];

                dates = dates.concat("<li>" + day + ' ' + monthPart.substring(0,3) + ' ' + year + "</li>");
            }    
        }
        
    }

    return dates;

}

/*****************************************************************************************/
/// AddRelativeDate
/*****************************************************************************************/
function AddRelativeOffsetDate(dates, DayName, DateString, ScanFor, Days){
    
    if (ScanFor.indexOf(DateString.toLowerCase())){
        var date = new Date();
        var dayPart = '';
        var monthPart = '';
        var yearPart = '';  
     
        var dt = new Date();
        
        dt.getDay();
        
        dt = dt.addDays(Days);
        
        var weekdayPart = dt.getDay();
        var expectedDayPart = getDayInt(DayName);
        
        dt = dt.addDays(expectedDayPart - weekdayPart);
        
        
        
        dayPart = dt.getDate();
        monthPart = monthNames[dt.getMonth()];
        yearPart = dt.getFullYear();
        
        dates = dates.concat("<li>" + dayPart + ' ' + monthPart.substring(0,3) + ' ' + yearPart + "</li>");    
    }
    
    return dates;
}

/*****************************************************************************************/
/// AddRelativeDate
/*****************************************************************************************/
function AddRelativeDate(dates, DateString, ScanFor, Days){
    
    if (ScanFor.indexOf(DateString.toLowerCase())==0){
        var date = new Date();
        var dayPart = '';
        var monthPart = '';
        var yearPart = '';  
     
        var dt = new Date();
        
        dt = dt.addDays(Days);
        
        dayPart = dt.getDate();
        monthPart = monthNames[dt.getMonth()];
        yearPart = dt.getFullYear();
        
        dates = dates.concat("<li>" + dayPart + ' ' + monthPart.substring(0,3) + ' ' + yearPart + "</li>");    
    }
    
    return dates;
}


/*****************************************************************************************/
/// stringIsMonth
/*****************************************************************************************/
function stringIsMonth(testString){
    var returnVal = [];
    
    for (i=0;i<monthNames.length;i++) 
    //item in monthNames)
    {
        if (monthNames[i].toLowerCase().indexOf(testString.toLowerCase())==0){
            returnVal = returnVal.concat(monthNames[i]);
        }
    }
    
    return returnVal;
}

function monthStringAsInt(testString){
    var returnVal = [];
    
    for (i=0;i<monthNames.length;i++) 
    //item in monthNames)
    {
        if (monthNames[i].toLowerCase().indexOf(testString.toLowerCase())==0){
            return i;
        }
    }
    
    return -1;
}

/*****************************************************************************************/
/// stringIsMonth
/*****************************************************************************************/
function stringIsWeekday(testString){
    var returnVal = [];
    
    for (i=0;i<weekdayNames.length;i++) 
    //item in monthNames)
    {
        if (weekdayNames[i].toLowerCase().indexOf(testString.toLowerCase())==0){
            returnVal = returnVal.concat(weekdayNames[i]);
        }
    }
    
    return returnVal;
}
 
