var topRef, navRef, tabsRef, daysRef, channelsRef, overviewRef, detailRef;
var scrollToNow = true;
var dayDates = {};
var dayCount = 14;
var menuVisible = true;
var detailVisible = false;
var daysTargetX, daysCurX, daysTimerId = 0;
var detailModes = {
	BOTTOM: 0,
	RIGHT: 1,
	FLOAT: 2
}
var detailMode = detailModes.BOTTOM;
var detailRect = {
	top:300,
	left:300,
	width:300,
	height:300
};
var detailHeight = 200;
var detailWidth = 300;

var channelList = [
	"tvgenial.1",
	"tvgenial.2",
	"tvgenial.212",
	"tvgenial.214",
	"tvgenial.215",
	"tvgenial.216",
	"tvgenial.219",
	"tvgenial.105",
	"tvgenial.10",
	"tvgenial.6",
	"tvgenial.17",
	"tvgenial.19",
	"tvgenial.7",
	"tvgenial.26",
	"tvgenial.201",
	"tvgenial.213",
	"tvgenial.16",
	"tvgenial.9",
	"tvgenial.134",
	"tvgenial.183",
	"tvgenial.52",
	"tvgenial.34",
	"tvgenial.244",
	"tvgenial.72",
	"tvgenial.55",
	"tvgenial.36",
	"tvgenial.220"
];

function getRefs() {
	topRef = document.getElementById("top");
	leftRef = document.getElementById("left");
	navRef = document.getElementById("nav");
	channelsRef = document.getElementById("channels2");
	tabsRef = document.getElementById("tabs");
	daysRef = document.getElementById("days");
	headerRef = document.getElementById("header");
	overviewRef = document.getElementById("overview");
	detailRef = document.getElementById("detail");
	detailResizeRef = document.getElementById("detail_resize");
	detailContentRef = document.getElementById("detail_content");
};

function attachHandlers() {
	attachEventHandler(window, "resize", onResize);	
	attachEventHandler(document.body, "selectstart", onSelect, true);
	attachEventHandler(daysRef, "click", onDaySelect, false);
	attachEventHandler(channelsRef, "click", onChannelSelect, false);
	attachEventHandler(tabsRef, "click", onTabSelect, false);
	attachEventHandler(detailRef, "click", onDetailClick, false);
	attachEventHandler(detailResizeRef, "dragstart", onDetailResizeStart, false);
	attachEventHandler(detailResizeRef, "drag", onDetailResize, false);
	attachEventHandler(detailResizeRef, "dragend", onDetailResizeEnd, false);
	
};

function onResize() {
	adaptSize();
}

function adaptSize() {
	layout();
	if (overviewRef.contentWindow.onResize) overviewRef.contentWindow.onResize();
}

function initWindow() {
	layout();
	getRefs();
	attachHandlers();
	setDetailMode(detailModes.BOTTOM);
	generateDays();
	generateHeader();
	generateChannels();
	selectDay(formatDateStr(new Date(), true), 0);
}

function onSelect() {
	return false;
}

// <div class=\"day\" day="20080721">Mo<br>21.07.</div>"
function generateDays() {
	var daysRef = document.getElementById("days2"),
		buffer = [],
		today = new Date(),
		yesterday = new Date(),
		date = new Date(),
		avail = 0,
		count = 0,
		daysOfWeek = ["So", "Mo", "Di", "Mi", "Do", "Fr", "Sa"],
		year, month, day, dow;
	yesterday.setDate(yesterday.getDate()-1);
	date.setDate(date.getDate()-2);
	
	for (var i = 0; i < 30; i++) {

		year = date.getFullYear();
		month = date.getMonth() + 1;
		if (month < 10) month = "0" + month;
		day = date.getDate();
		if (day < 10) day = "0" + day;
		dow = daysOfWeek[date.getDay()];
		
		buffer.push("<div class=\"day");
		if (date.getMonth() == yesterday.getMonth() && date.getDate() == yesterday.getDate()) {
			avail = dayCount;
		}
		if (avail > 0) {
			buffer.push(" dayavailable");
		}
		if (date.getMonth() == today.getMonth() && date.getDate() == today.getDate()) {
			buffer.push(" dayselected");
		}
		buffer.push("\" day=\"");
		buffer.push(year);
		buffer.push(month);
		buffer.push(day);
		if (avail > 0) {
			count = dayCount - avail;
			buffer.push("\" count=\"");
			buffer.push(count);
			dayDates[count] = "" +  year + month + day;
			avail--;
		}
		buffer.push("\")>");	
		buffer.push(dow);
		buffer.push("<br>");
		buffer.push(day);
		buffer.push(".");
		buffer.push(month);
		buffer.push(".</div>");
		date.setDate(date.getDate()+1);
	}	
	
	daysRef.innerHTML = buffer.join("");
}

function generateHeader() {
	var buffer = [],
		channel,
		icon;
	channelCount = channelList.length;
	buffer.push("<div id=\"header_content\" style=\"width:");
	buffer.push(channelCount * 253);
	buffer.push("px\">\n");
	for (var i = 0; i < channelCount; i++) {
		channelId = channelList[i];
		channel = channels[channelId];
		channel.col = i;
		generateChannelEntry(buffer, channel, true);
	}
	buffer.push("</div>\n");
	var html = buffer.join("");
	headerRef.innerHTML = html;
}

function generateChannels() {
	var buffer = [],
		channel,
		icon;
	channelCount = channelList.length;
	for (var i = 0; i < channelCount; i++) {
		channelId = channelList[i];
		channel = channels[channelId];
		generateChannelEntry(buffer, channel, false);
	}
	var html = buffer.join("");
	channelsRef.innerHTML = html;
}

function generateChannelEntry(buffer, channel, headerEntry) {
	buffer.push("<div class=\"channel\" channel=\"");
	buffer.push(channel.id)
	buffer.push("\">");
	if (headerEntry && channel.url) {    
		buffer.push("<a href=\"");
		buffer.push(channel.url);
		buffer.push("\" target=\"_new\">")     
	}
	buffer.push("<img class=\"channellogo\" src=\"");
	buffer.push(channel.icon);
	buffer.push("\">")
	if (headerEntry && channel.url) {    
		buffer.push("</a>");
	}
	buffer.push("<div class=\"channeltext\">");
	buffer.push("<div class=\"channelname\">");
	buffer.push(channel.shortname);
	buffer.push("</div>");
	buffer.push("<div class=\"channeldesc\">");
	buffer.push(channel.name);
	buffer.push("</div>");
	buffer.push("</div>");
	buffer.push("</div>\n");
}

function onChannelSelect(event) {
	var ref = event.srcElement || event.target,
		channel;
	while (!(ref.className == "channel")) {
		ref = ref.parentNode;
	}
	channel = ref.getAttribute("channel");
	selectChannel(channel);	
}

function onDaySelect(event) {
	var ref = event.srcElement || event.target,
		day = ref.getAttribute("day"),
		count = ref.getAttribute("count");
	if (ref.className.indexOf("dayavailable") >= 0) {	
		selectDay(day, count);	
	}
}

function markSelectedDay(day) {
	var days2Ref = document.getElementById("days2"),
		days = days2Ref.childNodes,
		dayRef;
	for (var i = 0; i < days.length; i++) {
		dayRef = days[i];
		if (dayRef.className.indexOf("dayselected") > 0) dayRef.className = "day dayavailable";
		if (dayRef.getAttribute("day") == day) {
			dayRef.className = "day dayselected";
			var width = daysRef.offsetWidth,
				left = dayRef.offsetLeft - daysRef.scrollLeft,
				diff = 0;
			if (left < width * 0.25) diff = Math.floor(left - width * 0.25)
			if (left > width * 0.5) diff = Math.floor(left - width * 0.5)
			if (diff != 0) {	
				var newScrollLeft = daysRef.scrollLeft + diff;
				if (newScrollLeft < 0) newScrollLeft = 0;
				scrollDaysTo(newScrollLeft); 
			}
		}
	}
}

function scrollDaysTo(scrollLeft) {
	daysTargetX = scrollLeft;
	daysCurX = daysRef.scrollLeft;
	if (daysTimerId == 0) {
		daysTimerId = setInterval(smoothDayScroll, 20);
	}
}

function smoothDayScroll() {
	var stepX = daysCurX + (daysTargetX - daysCurX) / 4,
		roundedStepX = Math.round(stepX);
	daysRef.scrollLeft = roundedStepX;
	daysCurX = stepX;
	if (roundedStepX == daysTargetX) {
		clearInterval(daysTimerId);
		daysTimerId = 0;
		daysCurX = daysTargetX;
	}
}

function selectChannel(channel) {
	var col = channels[channel].col;
	if (overviewRef.contentWindow.showColumn) overviewRef.contentWindow.showColumn(col);
	
	if (window.pageTracker) {
		var channelName = channels[channel].shortname;
		pageTracker._trackPageview("/channel:" + channelName);
	}
}

function selectDay(day, count) {
	if (overviewRef.contentWindow.showDay) overviewRef.contentWindow.showDay(count);
	
	if (window.pageTracker) {
		pageTracker._trackPageview("/day:" + day);
	}
}

function onTabSelect(event) {
	var ref = event.srcElement || event.target,
		id = ref.getAttribute("id");
	switch(id) {
		case "tab_jetzt": overviewRef.contentWindow.scrollToTime("now"); break;
		case "tab_frueh": overviewRef.contentWindow.scrollToTime("morning"); break;
		case "tab_tag": overviewRef.contentWindow.scrollToTime("day"); break;
		case "tab_abend": overviewRef.contentWindow.scrollToTime("evening"); break;
		case "tab_toggle": toggleMenu(); break;
		case "tab_split": toggleDetail(); break;
	}
}

function toggleMenu() {
	if (menuVisible) {
		leftRef.style.display = "none";
	} else {
		leftRef.style.display = "block";
	}
	menuVisible = !menuVisible;
	adaptSize();
}

function toggleDetail() {
	if (detailVisible) {
		detailRef.style.display = "none";
	} else {
		detailRef.style.display = "block";
	}
	detailVisible = !detailVisible;
	adaptSize();
}

function showDetailInfo(html, more, channel, start, stop) {
	updateDetailInfo(html, channel, start, stop);
	if (!detailVisible) toggleDetail();
	if (more) {
		var date = start.substr(0,8),
			url = "data/" + date + "/" + channel + "/" + start + ".html",
			xhrobj = getXHR(),
			xhr = xhrobj.xhr;
		xhr.open("GET", url, true);
		xhr.onreadystatechange = function() {
			var done = 4, ok = 200;
			if (xhr.readyState == done && xhr.status == ok) {
				onDetailLoaded(xhrobj, channel, start, stop);
				delete xhr.onreadystatechange;
			}
		};
		xhr.send(null);
	}
	
	if (window.pageTracker) {
		var channelName = channels[channel].shortname;
		pageTracker._trackPageview("/detail:" + channelName + ":" + start);
	}
}

function hideDetailInfo() {
	if (detailVisible) toggleDetail();
}

function onDetailLoaded(xhrobj, channel, start, stop) {
	if (detailVisible) {
		if (xhrobj.xhr.responseText) {
			updateDetailInfo(xhrobj.xhr.responseText, channel, start, stop);
		}
	}
	releaseXHR(xhrobj);
}

function updateDetailInfo(html, channel, start, stop) {
	var channelName = channels[channel].shortname,
		startDate = parseDate(start),
		stopDate = parseDate(stop),
		formattedDate = formatDate(start),
		channelHtml = "<div class=\"channel\">" + channelName + " (" + formattedDate + ")</div>",
		duration = Math.floor((stopDate.getTime() - startDate.getTime()) / 60000),
		durationHtml = "<div class=\"duration\">Dauer: ~" + duration + " Minuten</div>";

	html = html.replace(/((<div class="?desc"?>)|(<\/div>$))/i, channelHtml + "$1");
	html = html.replace(/(<\/div>$)/i, durationHtml + "$1");
		
	detailContentRef.innerHTML = html;
}

function onDetailResizeStart(event) {
	detailResizeWidth = detailRef.offsetWidth;
	detailResizeHeight = detailRef.offsetHeight;
}

function onDetailResize(event) {
	switch(detailMode) {
		case detailModes.FLOAT: 
			detailRef.style.width = (detailResizeWidth - event.dx) + "px"; 
			detailRef.style.height = (detailResizeHeight - event.dy) + "px"; 
			break;
		case detailModes.BOTTOM: 
			detailRef.style.height = (detailResizeHeight + event.dy) + "px"; 
			break;
		case detailModes.RIGHT: 
			detailRef.style.width = (detailResizeWidth + event.dx) + "px"; 
			break;
	}
	adaptSize();
}

function onDetailResizeEnd(event) {
	switch(detailMode) {
		case detailModes.FLOAT: 
			detailRect.width = detailRef.offsetWidth; 
			detailRect.height = detailRef.offsetHeight; 
			break;
		case detailModes.BOTTOM: 
			detailHeight = detailRef.offsetHeight; 
			break;
		case detailModes.RIGHT: 
			detailWidth = detailRef.offsetWidth; 
			break;
	}
}


function onDetailClick(event) {
	var src = event.srcElement || event.target;
	if (src.id == "detail_close") {
		overviewRef.contentWindow.clearSelection();
	}
	if (src.id == "detail_toggle") {
		var newDatailMode;
		switch(detailMode) {
			//case detailModes.FLOAT: newDetailMode = detailModes.BOTTOM; break;
			case detailModes.BOTTOM: newDetailMode = detailModes.RIGHT; break;
			case detailModes.RIGHT: newDetailMode = detailModes.BOTTOM; break;
		}
		setDetailMode(newDetailMode);
	}
}

function setDetailMode(mode) {
	detailMode = mode;
	switch(detailMode) {
		case detailModes.BOTTOM:  
			detailRef.className = "bottom detailbottom";
			detailRef.style.height = detailHeight + "px";
			detailRef.style.width = "auto";
			detailRef.style.border = "0px";
			detailResizeRef.className = "top";
			detailResizeRef.style.height = "5px";
			detailResizeRef.style.cursor = "row-resize";
			break;
		case detailModes.RIGHT: 
			detailRef.className = "right detailright";
			detailRef.style.width = detailWidth + "px";
			detailRef.style.height = "auto";
			detailRef.style.border = "0px";
			detailResizeRef.className = "left";
			detailResizeRef.style.width = "5px";
			detailResizeRef.style.cursor = "col-resize";
			break;
		case detailModes.FLOAT: 
			detailRef.style.bottom = "auto";
			detailRef.style.right = "auto";
			for (var i in detailRect) {
				detailRef.style[i] = detailRect[i] + "px";
			}
			detailRef.style.border = "2px solid gray";
			detailResizeRef.className = "float";
			break;
	}
	adaptSize();
}

attachEventHandler(window, "load", initWindow);



