// create & edit event

var MAX_YEARS_FROM_NOW = 5;

var NOTIFY_CONTACT = "C";
var NOTIFY_SELF = "S";

var PROMPT_ALARM = 'Please specify WHEN to remind (at Remind Time section)';
var PROMPT_HOW = 'Please select at least one device (at Remind Me By section)';
var PROMPT_CONTACT = 'Please select at least one contact (at Notify My Contacts section)';

/****************************
   alarm
*****************************/
function doOnTime(which) {
    var txtExactDate = document.getElementById(getClientId('txtExactDate' + which));
    var txtExactTime = document.getElementById(getClientId('txtExactTime' + which));

    var txtEventDate = document.getElementById(getClientId('txtEventDate'));
    var txtEventTime = document.getElementById(getClientId('txtEventTime'));

    txtExactDate.value = txtEventDate.value;
    txtExactTime.value = txtEventTime.value;

    var chkExact = document.getElementById(getClientId('chkExact' + which));
    chkExact.checked = true;
}

function doNumberChange(ddlNumber) {
    clearMessage();

    // save selectedIndex to corresponding hidden field (hfSelectedValue[1-3])
    var which = getControlNumberFromId(ddlNumber.id);
    
    var hfSelectedValueId = 'hfSelectedValue' + which;
    var hfSelectedValue = document.getElementById(getClientId(hfSelectedValueId));

    hfSelectedValue.value = ddlNumber.options[ddlNumber.selectedIndex].text;

    doShowRelativeTime(which);
}

function doShowRelativeTime(which) {
    clearMessage();

    var lblRelative = document.getElementById(getClientId('lblRelative' + which));
    var chkRelative = document.getElementById(getClientId('chkRelative' + which));

    if (!chkRelative.checked) {
        lblRelative.innerText = '';
        return;
    }

    var hfSelectedValue = document.getElementById(getClientId('hfSelectedValue' + which));

    if (hfSelectedValue.value == 0)
        lblRelative.innerText = '(on time)';
    else
        lblRelative.innerText = '';

    return;
}

function doTimeUnitChange(ddlTimeUnit) {// which reminder
    clearMessage();

    var which = getControlNumberFromId(ddlTimeUnit.id);

    var ddlNumberId = 'ddlNumber' + which;
    var ddlNumber = document.getElementById(getClientId(ddlNumberId));

    var hfSelectedValueId = 'hfSelectedValue' + which;
    var hfSelectedValue = document.getElementById(getClientId(hfSelectedValueId));
    
    //wipe out entire number dropdownlist
    while (ddlNumber.options.length)
        ddlNumber.remove(0);
        
    // create a new number list
    var newOpt;
    switch (ddlTimeUnit.value.toLowerCase()) {
        case 'minute':
            var arrMinute = new Array(0, 1, 2, 3, 4, 5, 10, 15, 20, 25, 30);
            
            for (var i = 0; i < arrMinute.length; i++) {
                newOpt = document.createElement("OPTION");
                newOpt.text = arrMinute[i];
                ddlNumber.add(newOpt, ddlNumber.length);
            }
            ddlNumber.selectedIndex = 0;
            break;
        case 'hour':
            for (var i = 0; i <= 12; i++) {
                newOpt = document.createElement("OPTION");
                newOpt.text = i;
                ddlNumber.add(newOpt, ddlNumber.length);
            }
            ddlNumber.selectedIndex = 1;
            break;
        case 'day':
            for (var i = 0; i <= 30; i++) {
                newOpt = document.createElement("OPTION");
                newOpt.text = i;
                ddlNumber.add(newOpt, ddlNumber.length);
            }
            ddlNumber.selectedIndex = 1;
            break;
    }

    hfSelectedValue.value = ddlNumber.options[ddlNumber.selectedIndex].text;
    
    doShowRelativeTime(which);
}

function getControlNumberFromId(idString) {
    // return last character, item# of reminder time section
    return idString.substring(idString.length - 1);
}

/****************************
   recurring
*****************************/
function doRepeat(ddlRepeat){
    clearMessage();

    var lastWeekdayClientId = getClientId('lblLastWeek');
    if (ddlRepeat.value == '10')
    	showArea(lastWeekdayClientId);
    else
    	hideArea(lastWeekdayClientId);
    
    // store ddl selected value to hidden field
    var hfRepeat = document.getElementById(getClientId('hfRepeat'));
    hfRepeat.value = ddlRepeat.value;

    // at this point, return when there is no repeat
    if (ddlRepeat.value <= 0)
        return;

    // Set RepeatEndDate, when there is a repeat and EventDate is valid
    var txtEventDate = document.getElementById(getClientId('txtEventDate'));
    var strEventDate = trim(txtEventDate.value);
    var txtRepeatEndDate = document.getElementById(getClientId('txtRepeatEndDate'));

    var strRepeatEndDate = trim(txtRepeatEndDate.value);
    
    var nextDate = new Date(strEventDate);
    var day = nextDate.getDate();
    var month = nextDate.getMonth();    // zero base
    var year = nextDate.getFullYear();

    var daysOfMonth = new Array(31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31);
    if (isLeapYear(year))
        daysOfMonth[1] = 29;
                    
    if (strEventDate.length == 0 || isUSDate(strEventDate) == false)  // when blank or invalid date  
        showWarningMessage('Start date is blank or invalid. We are not able to adjust the end date for you.');
    else {
        switch (ddlRepeat.value){
            case '1':     // daily
                nextDate.setDate(day + 1);
                break;
            case '2':     // weekly
                nextDate.setDate(day + 7);
                break;
            case '3':     // bi-weekly
                nextDate.setDate(day + 14);
                break;
            case '4':     // monthly
                nextDate.setDate(day + daysOfMonth[month]);
                break;
            case '5':     // weekday only
                nextDate.setDate(day + 7);
                break;
            case '6':     // weekend only
                nextDate.setDate(day + 7);
                break;
            case '7':     // quarterly
                nextDate.setMonth(month + 3);
                break;
            case '8':     // half yearly
                nextDate.setMonth(month + 6);
                break;
            case '9':     // yearly
                nextDate.setYear(year + 1);
                break;
            case '10':     // same weekday monthly
                // set to the end of next month
                nextDate.setMonth(month + 1);
                nextDate.setDate(daysOfMonth[(month + 1) % 12]);
                break;
        }
        
        var strNextDate = (nextDate.getMonth() + 1) + '/' +     // month
                          nextDate.getDate() + '/' +            // day
                          nextDate.getFullYear();               // year
        
        if (strRepeatEndDate.length == 0 ||             // EndDate is blank
            isUSDate(strRepeatEndDate) == false ||      // EndDate is invalid
            new Date(strRepeatEndDate) < nextDate       // EndDate is not meaningful
            )
            txtRepeatEndDate.value = strNextDate;   // change EndDate to the next closest meaningful date
    }
}

/****************************
   misc "do"
*****************************/
function doEventDetailDelete(){
    var prompt;
    var isSeries = document.getElementById(getClientId('hfIsSeries')).value;
    if (isSeries){
        var rbSeries = document.getElementById(getClientId('rbSeries'));
        prompt = rbSeries.checked ? 'Delete entire event or reminder series?' : 
            'Delete only this event or reminder while leaving the others intact?';
    } else {
        prompt = 'Delete this event or reminder?';
    }
    
    return confirm(prompt);
}

/****************************
   validateion
*****************************/

function validateAll(){
    // leave alarm time validation to server side, hard to do in client side
    if (validateEventDateTime(true) && 
        validateRepeat() && 
        validateSubject() && 
        validateRemindTimes()
       )
    {
        return true;
    } else {
        window.scrollTo(0, 0);  // remove scrolling so user can see error message on the top
        return false;
    }
}

function validateSubject(displayLabel){
    // check subject
    var txtSubject = document.getElementById(getClientId('txtSubject'));
    txtSubject.value = trim(txtSubject.value);          // trim subject input and write back
    if (txtSubject.value.length == 0) {
        showErrorMessage((displayLabel ? displayLabel : 'Subject') + ' is blank');
        txtSubject.focus();
        return false;
    }
    return true;
}

function validateEventDateTime(checkRecuring, timeDisplayLabel, dateDisplayLabel){
    // check event date & time
    if (!timeDisplayLabel)
        timeDisplayLabel = 'Event Time';
    if (!dateDisplayLabel)
        dateDisplayLabel = 'Event Date';
        
    var txtEventTime = document.getElementById(getClientId('txtEventTime'));
    var txtEventDate = document.getElementById(getClientId('txtEventDate'));

    var strTime = trim(txtEventTime.value);
    var strDate = trim(txtEventDate.value);

    txtEventTime.value = strTime;  // write back
    txtEventDate.value = strDate;
    
    if (strTime.length == 0) {
        showErrorMessage(timeDisplayLabel + ' is blank');
        txtEventTime.focus();
        return false;
    }

    if (isTime(strTime) == false) {
        showErrorMessage(timeDisplayLabel + ' is invalid');
        txtEventTime.focus();
        return false;
    }
    
    if (strDate.length == 0) {
        showErrorMessage(dateDisplayLabel + ' is blank');
        txtEventDate.focus();
        return false;
    }

    if (isUSDate(strDate) == false) {
        showErrorMessage(dateDisplayLabel + ' is invalid');
        txtEventDate.focus();
        return false;
    }
    
/* leave following checks to server, because JavaSCript use client time, 
   which may be different with server time and time zone can be different
   
    1. check if event' datetime is later than present time
    2. check if date is too far away into future, timezone does not matter here
*/    
    if (!checkRecuring)
        return true;

    /***** continue checking recuring related *****/
    
    var ddlRepeat = document.getElementById(getClientId('ddlRepeat'));
    var dayOfWeek = (new Date(strDate)).getDay();
    
    if (ddlRepeat.value == 5 &&     // repeat weeekday only
        (dayOfWeek == 0 || dayOfWeek == 6)  // week end
       )
    { 
        showErrorMessage('Event should start at a weekday because it recurs on weekday');
        txtEventDate.focus();
        return false;
    }

    if (ddlRepeat.value == 6 &&     // repeat weekend only
         dayOfWeek >= 1 && dayOfWeek <= 5)  // week day
    { 
        showErrorMessage('Event should start at a weekend because it recurs on weekend');
        txtEventDate.focus();
        return false;
    }

    return true;
}

function validateRepeat(){
    // check repeat event
    var ddlRepeat = document.getElementById(getClientId('ddlRepeat'));
    if (ddlRepeat.selectedIndex <= 0)   // no repeat
        return true;
        
    var txtRepeatEndDate = document.getElementById(getClientId('txtRepeatEndDate'));
    var strRepeatEndDate = trim(txtRepeatEndDate.value);
    txtRepeatEndDate.value = strRepeatEndDate;
    
    if (strRepeatEndDate.length == 0) {
        showErrorMessage('Recurs Until is blank');
        txtRepeatEndDate.focus();
        return false;
    }
    if (isUSDate(strRepeatEndDate) == false) {
        showErrorMessage('Recurs Until is invalid');
        txtRepeatEndDate.focus();
        return false;
    }
    
    // check if repeat end date later than start date
    var txtEventDate = document.getElementById(getClientId('txtEventDate'));
    var eventDate = new Date(txtEventDate.value);
    var repeatEndDate = new Date(strRepeatEndDate);
    
    if (repeatEndDate - eventDate <= 0) {
        showErrorMessage('Recurs Until should be later than start date');
        txtRepeatEndDate.focus();
        return false;
    }
    
    // check if end date is too far away into future
    var maxYear = (new Date()).getFullYear() + MAX_YEARS_FROM_NOW;
    if (repeatEndDate.getFullYear() > maxYear) {
        showErrorMessage('Recurs Until is more than ' + MAX_YEARS_FROM_NOW + ' years away');
        txtRepeatEndDate.focus();
        return false;
    }

    return true;
}

function validateNotification() { // no longer in use
    // check remind times and devices
    var hfCreateMode = document.getElementById(getClientId('hfCreateMode'));
    var hfNotifyWho = document.getElementById(getClientId('hfNotifyWho'));

    var isCreateMode = hfCreateMode.value == 1;
    var notifyContact = hfNotifyWho.value == NOTIFY_CONTACT;

    var alarmSelected = isThisAlarmSelected(1) || 
                        isThisAlarmSelected(2) || 
                        isThisAlarmSelected(3);

    var deviceSelected;
    var table;

    if (isCreateMode){
        if (notifyContact) {    // notify my contacts
            if (!alarmSelected)
                return reportNoAlarmSelected();

            table = document.getElementById(getContactGridViewClientId());
            deviceSelected = hasAnyBoxCheckedInContainer(table);

            if (!deviceSelected) {
                showErrorMessage(PROMPT_CONTACT);
                return false;
            }
        } else {    // remind myself and create event
            var notifySelf = hfNotifyWho.value == NOTIFY_SELF;
            
            if (!alarmSelected & notifySelf)
                return reportNoAlarmSelected();

            table = document.getElementById(getClientId('gvSelfDevice'));
            deviceSelected = hasAnyRowSelected(table.firstChild);
            
            if (!deviceSelected && notifySelf) {
                showErrorMessage(PROMPT_HOW);
                return false;
            }

            // device selected but not alarms
            if (deviceSelected && !alarmSelected)
                return reportNoAlarmSelected();
        }
    } else if (!alarmSelected) {    // edit event - devices and contacts can be unselected
        // check self devices
        table = document.getElementById(getClientId('gvSelfDevice'));
        deviceSelected = hasAnyRowSelected(table.firstChild);
        if (deviceSelected)
            return reportNoAlarmSelected();

        // check contacts
        if (notifyContact) {
            table = document.getElementById(getContactGridViewClientId());
            deviceSelected = hasAnyBoxCheckedInContainer(table);
            if (deviceSelected)
                return reportNoAlarmSelected();
        } 
    }

    return true;
}

function validateRemindTimes() {
    // only need to check exact time, no need on relative and default time
    if (document.getElementById(getClientId('exactTimePanel')))
        return validateExactTime(1) && validateExactTime(2) && validateExactTime(3);
    else
        return true;
}

function validateExactTime(which) {
    // check only: blank, invalid, maximum year
    var chkExact = document.getElementById(getClientId('chkExact' + which));
    if (!chkExact.checked)
        return true;
        
    var txtExactDate = document.getElementById(getClientId('txtExactDate' + which));
    var txtExactTime = document.getElementById(getClientId('txtExactTime' + which));

    var strDate = trim(txtExactDate.value);
    var strTime = trim(txtExactTime.value);

    // write back
    txtExactDate.value = strDate;
    txtExactTime.value = strTime;
    
    if (strDate.length == 0) {
        showErrorMessage('Reminder date is blank');
        txtExactDate.focus();
        return false;
    }

    if (isUSDate(strDate) == false) {
        showErrorMessage('Reminder date is invalid');
        txtExactDate.focus();
        return false;
    }
    
    if (strTime.length == 0) {
        showErrorMessage('Reminder time is blank');
        txtExactTime.focus();
        return false;
    }

    if (isTime(strTime) == false) {
        showErrorMessage('Reminder time is invalid');
        txtExactTime.focus();
        return false;
    }

    // leave the checks to server side: check if date is too far away into future

    return true;
}

function validateDateRange(){
    var txtBeginDate = document.getElementById(getClientId('txtBeginDate'));
    var txtEndDate = document.getElementById(getClientId('txtEndDate'));

    var strBeingDate = trim(txtBeginDate.value);
    var strEndDate = trim(txtEndDate.value);

    // write back
    txtBeginDate.value = strBeingDate;
    txtEndDate.value = strEndDate;
    
    if (strBeingDate.length == 0) {
        showErrorMessage('Event Date is blank');
        txtBeginDate.focus();
        return false;
    }

    if (isUSDate(strBeingDate) == false) {
        showErrorMessage('Event Date is invalid');
        txtBeginDate.focus();
        return false;
    }
    
    if (strEndDate.length == 0) {
        showErrorMessage('Recurs Until is blank');
        txtEndDate.focus();
        return false;
    }

    if (isUSDate(strEndDate) == false) {
        showErrorMessage('Recurs Until is invalid');
        txtEndDate.focus();
        return false;
    }
    
    return true;
}
/****************************
   misc utility
*****************************/
function isThisAlarmSelected(which) {
    var checkBoxNameStem;

    if (document.getElementById(getClientId('relativeTimePanel')))
        checkBoxNameStem = 'chkRelative';
    else if (document.getElementById(getClientId('exactTimePanel')))
        checkBoxNameStem = 'chkExact';
    else if (document.getElementById(getClientId('defaultTimePanel')))
        checkBoxNameStem = 'chkDefault';
    
    var chkOne = document.getElementById(getClientId(checkBoxNameStem + which));
    
    return chkOne.checked;
}

function reportNoAlarmSelected() {
    showErrorMessage(PROMPT_ALARM);
    var ddlNumber1 = document.getElementById(getClientId('ddlNumber1'));
    if (ddlNumber1)
        ddlNumber1.focus();
    else {
        var txtExactDate1 = document.getElementById(getClientId('txtExactDate1'));
        txtExactDate1.focus();
    }
    
    return false;
}

function requireSelectOneDevice() {
    var table = document.getElementById(getClientId('gvSelfDevice'));

    if (!hasAnyRowSelected(table.firstChild)) {
        showErrorMessage("Please select at least one device");
        return false;
    }

    return true;
}

/****************************
   client callback
*****************************/
function previewResult(eventId, contactName) {
    showResult("Loading ...");
    CallServer(eventId + "," + contactName, '');
}

function ClientCallback(value, context){
    showResult(value);
}
function ClientErrorCallback(error, context){
    var pos = error.indexOf('.');
    showResult(pos == 0 ? error : error.substring(0, pos + 1));
}

function showResult(content) {
    // show the content
    var phonePreviewArea = document.getElementById('phonePreviewArea');
    var phonePreviewAreaContent = document.getElementById('phonePreviewAreaContent');
    
    phonePreviewArea.style.display = '';

    if (typeof(phonePreviewAreaContent.textContent) != "undefined"){ // for FF
		phonePreviewAreaContent.textContent = content;
    } else { // for IE
		phonePreviewAreaContent.innerText = content;
    }

    // adjust position for large screen
    phonePreviewArea.left = phonePreviewArea.style.left + getMasterAbsoluteLeft();
    phonePreviewArea.top = phonePreviewArea.style.top + getMasterAbsoluteTop();
}
