function openWindow(url, name) {
    popupWin = window.open(url, name, "scrollbars,resizable,width=640,height=480,left=0,top=0");
    popupWin.focus();
}

function lineUpTabBg() {
    var tds = document.getElementsByTagName('TD')
    for(x in tds)
        if (tds[x].className != null && tds[x].className.match(/^navtab.+?on$/))
            if(tds[x].offsetLeft < 300)
                tds[x].style.backgroundPosition = '-' + tds[x].offsetLeft + 'px 0px'
            else
                tds[x].style.backgroundPosition = 'top right';
}

var ampmEnabled = true;

var monthNumberToDaysInMonth = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
var monthNumberToMonthName = [
    'January',
    'February',
    'March',
    'April',
    'May',
    'June',
    'July',
    'August',
    'September',
    'October',
    'November',
    'December'];
var dayOfWeekNumberToDayOfWeekName = [
    'Sunday',
    'Monday',
    'Tuesday',
    'Wednesday',
    'Thursday',
    'Friday',
    'Saturday'];

var mainMode;
var mainStart;
var mainEnd;

function mainRepaintDayCols(startDate, endDate) {
    mainMode = 'RepaintDayCols';
    mainStart = startDate;
    mainEnd = endDate;

    var tmpInnerHtml = '';

    var hour = 0;
    var minute = 0;
    do {
        var ampm = '';
        var tmpHour = hour;
        var tmpMinute = minute;
        if(ampmEnabled) {
            if(tmpHour < 12)
                ampm = 'am';
            else
                ampm = 'pm';
            if(tmpHour == 0 || tmpHour == 24)
                tmpHour = 12
            else if(tmpHour > 12)
                tmpHour -= 12;
        }
        if(tmpMinute < 10)
            tmpMinute = '0' + tmpMinute;
        if(minute == 0)
            tmpInnerHtml += '<div class="mainTimeHour">' + tmpHour + ampm + '</div>';
        else
            tmpInnerHtml += '<div class="mainTimeHalf"></div>';
        minute += 30;
        if(minute == 60) {
            hour++;
            minute = 0;
        }
    } while(hour < 24);

    document.getElementById('mainTimeCol').innerHTML = tmpInnerHtml;

    tmpInnerHtml = '';
    var tmpDate = startDate;
    var now = new Date();
    var dayCount = 0;
    while(tmpDate.getTime() <= endDate.getTime()) {
        hour = 0;
        minute = 0;
        var classValue = '';
        if(tmpDate.getFullYear() == now.getFullYear())
            if(tmpDate.getMonth() == now.getMonth())
                if(tmpDate.getDate() == now.getDate())
                    classValue = 'mainToday';
        tmpInnerHtml += '<td class="' + classValue + '">';
        do {
            ampm = '';
            tmpHour = hour;
            tmpMinute = minute;
            if(ampmEnabled) {
                if(tmpHour < 12)
                    ampm = 'am';
                else
                    ampm = 'pm';
                if(tmpHour == 0 || tmpHour == 24)
                    tmpHour = 12
                else if(tmpHour > 12)
                    tmpHour -= 12;
            }
            if(tmpMinute < 10)
                tmpMinute = '0' + tmpMinute;
            classValue = 'mainTimeHalf';
            if(minute == 0)
                classValue = 'mainTimeHour';
            tmpInnerHtml += '<div class="' + classValue + '"></div>';
            minute += 30;
            if(minute == 60) {
                hour++;
                minute = 0;
            }
        } while(hour < 24);
        tmpInnerHtml += '</td>';
        tmpDate = new Date(tmpDate.getFullYear(), tmpDate.getMonth(), tmpDate.getDate() + 1);
        dayCount++;
    }

    document.getElementById('mainEventCol').innerHTML =
    '<table cellpadding="0" cellspacing="0"><tr>' +
    tmpInnerHtml + '</tr></table>';

    tmpInnerHtml = '';
    
    var width = parseInt(1/dayCount*100);

    tmpDate = startDate;
    while(tmpDate.getTime() <= endDate.getTime()) {
        hour = 0;
        minute = 0;
        classValue = '';
        if(tmpDate.getFullYear() == now.getFullYear())
            if(tmpDate.getMonth() == now.getMonth())
                if(tmpDate.getDate() == now.getDate())
                    classValue = 'mainHeaderToday';
        tmpInnerHtml += '<td class="mainHeaderSpacer"><br /></td>';
        tmpInnerHtml += '<td class="' + classValue + '" style="width: ' + width + '%">';
        tmpInnerHtml += '<div>';
        tmpInnerHtml += dayOfWeekNumberToDayOfWeekName[tmpDate.getDay()] + ' ' + (1 + tmpDate.getMonth()) + '/' + tmpDate.getDate();
        tmpInnerHtml += '</div>';
        tmpInnerHtml += '</td>';
        tmpDate = new Date(tmpDate.getFullYear(), tmpDate.getMonth(), tmpDate.getDate() + 1);
    }

    document.getElementById('mainHeaderEventCol').innerHTML =
    '<table cellpadding="0" cellspacing="0"><tr>' +
    tmpInnerHtml + '</tr></table>';

    document.getElementById('controllsMainRange').innerHTML = monthNumberToMonthName[mainStart.getMonth()] + ' ' + mainStart.getDate() + ' through ' + monthNumberToMonthName[mainEnd.getMonth()] + ' ' + mainEnd.getDate() + ', ' + mainEnd.getFullYear();

    tmpDate = new Date(mainStart.getTime() + (mainEnd.getTime() - mainStart.getTime()) / 2);

}

function positionPage() {
    var main = document.getElementById('main');
    document.getElementById('mainHeaderTable').style.width =
    document.getElementById('mainTable').style.width = main.clientWidth + 'px';
    document.getElementById('availability').style.left = document.getElementById('mainEventCol').offsetLeft + 'px';
    document.getElementById('availability').style.top = '0px';
    document.getElementById('availability').style.width = (document.getElementById('main').clientWidth - document.getElementById('mainEventCol').offsetLeft) + 'px';
    document.getElementById('mainHeaderTimeCol').style.width = document.getElementById('mainTimeCol').offsetWidth + 'px';
    availabilityPageAvailabilityRepaintLabels();
    availabilityPagePublishedEventsRepaint();
}

function mainInit() {
    var tmpDate = new Date();
    tmpDate = new Date(tmpDate.getFullYear(), tmpDate.getMonth(), tmpDate.getDate() - tmpDate.getDay());
    mainRepaintDayCols(tmpDate, new Date(tmpDate.getFullYear(), tmpDate.getMonth(), tmpDate.getDate() + 6));
    document.getElementById('controllsMainToday').className = 'controllsMainTodayDisabled';
    positionPage();
}

function formatHtml(input) {
    return input.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/\n/g,"<br />\n");
}

function availabilityPageAvailabilityRepaintLabels() {
    var masterDiv = document.getElementById('availabilityLabels');
    masterDiv.style.display = 'none';
    masterDiv.innerHTML = '';
    var mainEventCol = document.getElementById('mainEventCol')
    var tmpDate = mainStart;
    tmpDate = new Date(tmpDate.getFullYear(), tmpDate.getMonth(), tmpDate.getDate());
    while(tmpDate.getTime() <= mainEnd.getTime()) {
        for(var x in window.availabilityData) {
            if(!availabilityData[x].label.match(/^\s*$/)) {
                if(
                    availabilityData[x].repeat == 'None' &&
                    availabilityData[x].start.getFullYear() == tmpDate.getFullYear() &&
                    availabilityData[x].start.getMonth() == tmpDate.getMonth() &&
                    availabilityData[x].start.getDate() == tmpDate.getDate()) {
                // Skip the else and work instead of continue
                } else if(!availabilityData[x].label.match(/^\s*$/) &&
                    availabilityData[x].repeat == 'Weekly' &&
                    availabilityData[x].start.getDay() == tmpDate.getDay()) {
                // Skip the else and work instead of continue
                } else
                    continue;
                var div = document.createElement('div');
                var extraTopPaddingTmpDate = new Date(mainStart.getFullYear(), mainStart.getMonth(), mainStart.getDate() + availabilityData[x].start.getDay(), availabilityData[x].start.getHours(), availabilityData[x].start.getMinutes(), availabilityData[x].start.getSeconds());
                var extraTopPadding = 0;
                    continual:
                    while(true) {
                        for(var y in availabilityData) {
                            if(availabilityData[y].start.getDate() > extraTopPaddingTmpDate.getDate())
                                continue;
                            if(availabilityData[y].available)
                                continue;
                            if(availabilityData[y].start.getTime() <= extraTopPaddingTmpDate.getTime())
                                if(availabilityData[y].end.getTime() > extraTopPaddingTmpDate.getTime()) {
                                    extraTopPaddingTmpDate = availabilityData[y].end;
                                    continue continual;
                                }
                        }
                        break;
                    }
                if(extraTopPaddingTmpDate.getTime() > availabilityData[x].start)
                    extraTopPadding = (-1 +
                        extraTopPaddingTmpDate.getHours() + extraTopPaddingTmpDate.getMinutes() / 60 -
                        availabilityData[x].start.getHours() + availabilityData[x].start.getMinutes() / 60) * 50;
                div.innerHTML = formatHtml(availabilityData[x].label);
                div.style.color = '#1C5C79';
                div.style.textTransform = 'uppercase';
                div.style.fontSize = '10px';
                div.style.textAlign = 'center';
                div.style.position = 'absolute';
                div.style.overflow = 'hidden';
                div.style.border = 'solid 1px #1C5C79';
                div.style.zIndex = 9;
                div.style.MozUserSelect = 'none';
                var index = tmpDate.getDay() - (mainStart.getDay() > tmpDate.getDay() ? mainStart.getDay() - 7 : mainStart.getDay());
                div.style.left = (mainEventCol.offsetLeft + 4 +
                    mainEventCol.firstChild.firstChild.firstChild.childNodes[index].offsetLeft) + 'px';
                div.style.top = ((availabilityData[x].start.getHours() * 60 + availabilityData[x].start.getMinutes()) * 25 / 30 + 1) + 'px';
                div.style.width = (mainEventCol.firstChild.firstChild.firstChild.childNodes[index].clientWidth - 8) + 'px';
                var areaHeight = (
                    (availabilityData[x].end.getHours() * 60 + availabilityData[x].end.getMinutes() -
                        availabilityData[x].start.getHours() * 60 - availabilityData[x].start.getMinutes())
                    ) * 25 / 30;
                if(extraTopPadding > areaHeight - 50)
                    extraTopPadding = 0;
                div.style.padding = extraTopPadding + 'px 2px 0px';
                div.style.height = (areaHeight - extraTopPadding - 5) + 'px';
                div.style.lineHeight = '11px';
                masterDiv.appendChild(div);
            }
        }
        tmpDate = new Date(tmpDate.getFullYear(), tmpDate.getMonth(), tmpDate.getDate() + 1);
    }
    masterDiv.style.display = 'block';
}

function availabilityPagePublishedEventsRepaint() {
    var masterDiv = document.getElementById('availabilityPublished');
    masterDiv.style.display = 'none';
    masterDiv.innerHTML = '';
    var mainEventCol = document.getElementById('mainEventCol')
    var tmpDate = mainStart;
    tmpDate = new Date(tmpDate.getFullYear(), tmpDate.getMonth(), tmpDate.getDate());
    while(tmpDate.getTime() <= mainEnd.getTime()) {
        for(var x in publishedEvents) {
            if(publishedEvents[x].getStartDate().getTime() < tmpDate.getTime())
                continue;
            if(publishedEvents[x].getStartDate().getTime() >= new Date(tmpDate.getFullYear(), tmpDate.getMonth(), tmpDate.getDate() + 1).getTime())
                continue;
            var div = document.createElement('div');
            div.innerHTML = formatHtml(publishedEvents[x].getNote());
            div.style.color = 'black';
            div.style.textTransform = 'uppercase';
            div.style.fontSize = '10px';
            div.style.textAlign = 'center';
            div.style.position = 'absolute';
            div.style.overflow = 'hidden';
            div.style.padding = '0px 2px';
            div.style.border = 'solid 1px #b7c218';
            div.style.zIndex = 9;
            div.style.MozUserSelect = 'none';
            div.style.MozBorderRadius = '3px';
            div.style.background = 'white';
            var index = tmpDate.getDay() - (mainStart.getDay() > tmpDate.getDay() ? mainStart.getDay() - 7 : mainStart.getDay());
            div.style.left = (mainEventCol.offsetLeft + 7 +
                mainEventCol.firstChild.firstChild.firstChild.childNodes[index].offsetLeft) + 'px';
            div.style.top = ((publishedEvents[x].getStartDate().getHours() * 60 + publishedEvents[x].getStartDate().getMinutes()) * 25 / 30 + 4) + 'px';
            div.style.width = (mainEventCol.firstChild.firstChild.firstChild.childNodes[index].clientWidth - 14) + 'px';
            div.style.height = (
                (
                    (publishedEvents[x].getEndDate().getHours() * 60 + publishedEvents[x].getEndDate().getMinutes() -
                        publishedEvents[x].getStartDate().getHours() * 60 - publishedEvents[x].getStartDate().getMinutes())
                    ) * 25 / 30
                - 11) + 'px';
            div.style.lineHeight = '11px';
            masterDiv.appendChild(div);
        }
        tmpDate = new Date(tmpDate.getFullYear(), tmpDate.getMonth(), tmpDate.getDate() + 1);
    }
    masterDiv.style.display = 'block';
}

function availabilityPagePaint() {
    positionPage();
    var div = document.getElementById('availability');
    div.innerHTML = '';
    var table = document.createElement('table');
    table.cellPadding = 0;
    table.cellSpacing = 0;
    table.style.width = '100%';
    var tr = table.insertRow(0);
    tr.style.verticalAlign = 'top';
    var tmpDate = mainStart;
    var blockStarts = new Array();
    var blockEnds = new Array();
    var blockAvailables = new Array();
    for (var x in availabilityData) {
        var block = availabilityData[x];
        var blockstart;
        var blockend;
        if(block.repeat == 'None') {
            blockstart = block.start;
            blockend = block.end;
        } else if(block.repeat == 'Weekly') {
            var startDayOfWeek = block.start.getDay();
            var startHour = block.start.getHours();
            var startMinute = block.start.getMinutes();
            blockstart = new Date(mainStart.getFullYear(), mainStart.getMonth(), mainStart.getDate());
            while(blockstart.getDay() != startDayOfWeek) {
                blockstart = new Date(blockstart.getFullYear(), blockstart.getMonth(), blockstart.getDate() + 1);
            }
            blockstart = new Date(blockstart.getFullYear(), blockstart.getMonth(), blockstart.getDate(), startHour, startMinute);
            blockend = new Date(blockstart.getTime() + block.end.getTime() - block.start.getTime());
        } else
            continue;
        if(mainStart.getTime() > blockend.getTime())
            continue;
        if(
            mainEnd.getFullYear() < blockstart.getFullYear() ||
            mainEnd.getFullYear() == blockstart.getFullYear() &&
            (
                mainEnd.getMonth() < blockstart.getMonth() ||
                (
                    mainEnd.getMonth() == blockstart.getMonth() &&
                    mainEnd.getDate() < blockstart.getDate())
                )
                )
            continue;
        blockStarts.push(blockstart);
        blockEnds.push(blockend);
        blockAvailables.push(availabilityData[x].available);
    }
    var minutesPerPixal = 30 / 25;
    while(tmpDate.getTime() <= mainEnd.getTime()) {
        var td = document.createElement('td');
        var hour = 0;
        var minute = 0;
        var pixelDiv = undefined;
        var lastTaken = undefined;
        do {
            var spotDate = new Date(tmpDate.getFullYear(), tmpDate.getMonth(),
                tmpDate.getDate(), hour, parseInt(minute));
                
            var taken = true;
            var addPixels = 0;
            
            for(x in blockStarts) {
                if(blockStarts[x].getTime() <= spotDate.getTime()) {
                    if(blockEnds[x].getTime() <= spotDate.getTime()) {
                        continue;
                    } else {
                        if(!blockAvailables[x]) {
                            taken = true;
                            break;
                        } else {
                            taken = false;
                        }
                    }
                }
            }
            
            if(taken == lastTaken)
                pixelDiv.style.height = (parseInt(pixelDiv.style.height.replace(/\D/g, '')) + 1 + addPixels) + 'px';
            else {
                if(pixelDiv != undefined)
                    td.appendChild(pixelDiv);
                pixelDiv = document.createElement("div");
                pixelDiv.className = 'availabilityPixelDiv' + (taken ? 'Taken' : '');
                pixelDiv.style.height = (addPixels + 1) + 'px';
                pixelDiv.appendChild(document.createElement('br'))
                pixelDiv.style.backgroundPosition = 'center ' + ("" + -(((hour + minute / 60) * 50) % 25)).replace(/^-?\d+(?:\.\d+)e-?\d+$/i, "0") + 'px';
            }
            
            minute += minutesPerPixal;
            while(minute >= 60) {
                hour++;
                minute -= 60;
            }
            
            lastTaken = taken;
            
        } while (hour < 24);
        
        if(pixelDiv != undefined) {
            td.appendChild(pixelDiv);
        }
        
        tr.appendChild(td);
        tmpDate = new Date(tmpDate.getFullYear(), tmpDate.getMonth(), tmpDate.getDate() + 1);
    }
    div.appendChild(table);
    
    // IE is not nice
    if(!document.getElementById('availability').firstChild.offsetHeight) {
        var temp = document.getElementById('availability').innerHTML;
        document.getElementById('availability').innerHTML = '';
        document.getElementById('availability').innerHTML = temp;
    }
    
    availabilityPageAvailabilityRepaintLabels();
    availabilityPagePublishedEventsRepaint();

}

function initializePage() {
    mainInit();
    positionPage();
    document.getElementById('main').scrollTop = 390;
    availabilityPagePaint();
}


function mainGoToDate(targetDate, scrollToDefault) {
    var now = new Date();
    var today = new Date(now.getFullYear(), now.getMonth(), now.getDate());
    var targetDay = new Date(targetDate.getFullYear(), targetDate.getMonth(), targetDate.getDate())
    if(mainMode == 'RepaintDayCols') {
        var dayDiff = 0;
        var tmpDate = mainStart;
        while(tmpDate.getTime() <= mainEnd.getTime()) {
            dayDiff++;
            tmpDate = new Date(tmpDate.getFullYear(), tmpDate.getMonth(), tmpDate.getDate() + 1);
        }
        if(dayDiff == 7 && mainStart.getDay() == 0) { // Week view
            if(mainStart.getTime() <= targetDay.getTime() && mainEnd.getTime() >= targetDay.getTime())
                return;
            tmpDate = targetDay;
            while(tmpDate.getDay() != 0) {
                tmpDate = new Date(tmpDate.getFullYear(), tmpDate.getMonth(), tmpDate.getDate() - 1);
            }
            mainRepaintDayCols(tmpDate, new Date(tmpDate.getFullYear(), tmpDate.getMonth(), tmpDate.getDate() + dayDiff - 1));
            if(today.getTime() >= mainStart.getTime() && today.getTime() <= mainEnd.getTime())
                document.getElementById('controllsMainToday').className = 'controllsMainTodayDisabled';
            else
                document.getElementById('controllsMainToday').className = 'controllsMainToday';
        } else {
            mainRepaintDayCols(targetDay, new Date(targetDay.getFullYear(), targetDay.getMonth(), targetDay.getDate() + dayDiff - 1));
            document.getElementById('controllsMainToday').className =
            targetDay.getTime() == today.getTime() ? 'controllsMainTodayDisabled' : 'controllsMainToday';
        }
    } else
        alert('Not Yet Implemented');
    if(scrollToDefault)
        document.getElementById('main').scrollTop = 390;
    availabilityPagePaint();
}

function mainNext() {
    mainGoToDate(new Date(mainEnd.getFullYear(), mainEnd.getMonth(), mainEnd.getDate() + 1), true);
}

function mainBack() {
    if(mainMode == 'RepaintDayCols') {
        var dayDiff = 0;
        var tmpDate = mainStart;
        while(tmpDate.getTime() <= mainEnd) {
            dayDiff++;
            tmpDate = new Date(tmpDate.getFullYear(), tmpDate.getMonth(), tmpDate.getDate() + 1);
        }
        mainGoToDate(new Date(mainStart.getFullYear(), mainStart.getMonth(), mainStart.getDate() - dayDiff), true);
    } else
        alert('Not Yet Implemented');
}

function mainToday() {
    if(document.getElementById('controllsMainToday').className != 'controllsMainTodayDisabled')
        mainGoToDate(new Date(), true);
}

function AvailabilityBlock(start, end, label, repeat, available) {
    this.start = start;
    this.end = end;
    this.label = label;
    this.repeat = repeat;
    this.available = available;
	this.toString = function () {
		return (available ? "availability window" : "unavailable time") + " from " + start + " to " + end;
	}
}

function PublishedEvent(startDate, endDate, note, participantLimit) {
    this.getEndDate = function () {
        return endDate;
    }
    this.getNote = function () {
        return note;
    }
    this.getParticipantLimit = function () {
        return participantLimit;
    }
    this.getStartDate = function () {
        return startDate;
    }
    this.toString = function () {
        return 'PublishedEvent' + " from " + startDate + " to " + endDate;
    }
}
