/***************************************************************
*  Copyright notice
*
*  (c) 2009 Ralf Hettinger <ng@ralfhettinger.de>
*  All rights reserved
*
*  This script is part of the TYPO3 project. The TYPO3 project is
*  free software; you can redistribute it and/or modify
*  it under the terms of the GNU General Public License as published by
*  the Free Software Foundation; either version 2 of the License, or
*  (at your option) any later version.
*
*  The GNU General Public License can be found at
*  http://www.gnu.org/copyleft/gpl.html.
*
*  This script is distributed in the hope that it will be useful,
*  but WITHOUT ANY WARRANTY; without even the implied warranty of
*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
*  GNU General Public License for more details.
*
*  This copyright notice MUST APPEAR in all copies of the script!
***************************************************************/



/* config */

var tx_broadcastplaylist_pi1_feedURL		= '/typo3temp/JS_playlistfeed.txt';
var tx_broadcastplaylist_pi1_hashURL		= '/typo3temp/JS_playlistfeed_hash.txt';
var tx_broadcastplaylist_pi1_scheduleURL	= '/typo3temp/JS_schedulesfeed.txt';
var tx_broadcastplaylist_pi1_listId			= 'onAir_list';
var tx_broadcastplaylist_pi1_broadcastId	= 'onAir_heading';
var tx_broadcastplaylist_pi1_containerId	= 'onAir_container';
var tx_broadcastplaylist_pi1_scrollId		= 'onAir_scroll';
var tx_broadcastplaylist_pi1_bannerId		= 'nowOnAir_banner';
var tx_broadcastplaylist_pi1_bannerDir		= 'uploads/tx_broadcastplaylist/';
var tx_broadcastplaylist_pi1_broadcastPre	= 'On Air: ';

// ATTENTION: If you change this, make sure your webserver doesn't block by adjusting keep alive timeout and requests consistently
var tx_broadcastplaylist_pi1_interval		= 30000;		//milliseconds fpr refetchig the content

var tx_broadcastplaylist_pi1_timezoneOffset	= 60;		//given in minutes: offset of server time to UTC; Winterzeit: 60; Sommerzeit: 120
var tx_broadcastplaylist_pi1_maxOffsetTime	= 1200;		//offset in seconds - if the last track is older we fall back to fallbackTitle
var tx_broadcastplaylist_pi1_fallbackTitle	= 'zur zeit läuft ein live-mix'; //fallback title
var tx_broadcastplaylist_pi1_catSpecial		= '31';
var tx_broadcastplaylist_pi1_catSpecialText	= 'Tracklist nach der Sendung';

var tx_broadcastplaylist_pi1_appendGP	= true; // if true, a dummy parameter will be appended to prevent caching. 

/* end: config */


/* global vars */

var tx_broadcastplaylist_pi1_debug = 0;

var tx_broadcastplaylist_pi1_lastExport	= '';
var tx_broadcastplaylist_pi1_broadcast = null;
var tx_broadcastplaylist_pi1_list = null;
var tx_broadcastplaylist_pi1_image = '';
var tx_broadcastplaylist_pi1_lasttrackhour = 0;
var tx_broadcastplaylist_pi1_lasttracktstamp = 0;
var tx_broadcastplaylist_pi1_isInFallBackMode = 0;
var tx_broadcastplaylist_pi1_now = 0;
var tx_broadcastplaylist_pi1_elementList = Array();
var tx_broadcastplaylist_pi1_timezoneCorrection = 0;

/***/



/* main */

window.addEvent('domready', function() {

	// get elements to update
	tx_broadcastplaylist_pi1_list		= $(tx_broadcastplaylist_pi1_listId);
	tx_broadcastplaylist_pi1_broadcast	= $(tx_broadcastplaylist_pi1_broadcastId);
	tx_broadcastplaylist_pi1_container 	= $(tx_broadcastplaylist_pi1_containerId);
	tx_broadcastplaylist_pi1_banner		= $(tx_broadcastplaylist_pi1_bannerId);

	// populate elements
	update_nowPlaying();

	// populate elements all n milliseconds
	update_nowPlaying.periodical(tx_broadcastplaylist_pi1_interval);
});

var update_nowPlaying = function() {
	var localTime = new Date()

//ralfhe 2010-11-01:fix for sommerzeit / winterzeit. tx_broadcastplaylist_pi1_timezoneCorrection has to be zero always.is this correct?
//	tx_broadcastplaylist_pi1_timezoneCorrection = (localTime.getTimezoneOffset() + tx_broadcastplaylist_pi1_timezoneOffset) * 60 * 1000;
	tx_broadcastplaylist_pi1_timezoneCorrection = 0;
	tx_broadcastplaylist_pi1_now = new Date();
	tx_broadcastplaylist_pi1_now.setTime(tx_broadcastplaylist_pi1_now.getTime() + tx_broadcastplaylist_pi1_timezoneCorrection);


	// dummy get params forcing that this stuff doesn't get cached
	var dummyGP = '';
	if (tx_broadcastplaylist_pi1_appendGP) {
		var dummyGP = '?dummy=' + tx_broadcastplaylist_pi1_now.getTime();
	}


	// render tracks - default
	var jsonRequest1 = new Request.JSON({
		url: tx_broadcastplaylist_pi1_hashURL + dummyGP,
		method: 'get',
		onComplete: function(dataObj) {
			var currentHash = dataObj['exported'];

			// only do something if update required
			if (	tx_broadcastplaylist_pi1_lastExport == '' ||
				tx_broadcastplaylist_pi1_lastExport != currentHash || 
				tx_broadcastplaylist_pi1_debug == 1
			) {
				// store update hash.
				tx_broadcastplaylist_pi1_lastExport = currentHash;

				// fire second request to actually get the data.
				var jsonRequest2 = new Request.JSON({
					url: tx_broadcastplaylist_pi1_feedURL + dummyGP,
					method: 'get',
					onComplete: function(dataObj) {

						// populate and render the list
						tx_broadcastplaylist_pi1_getListContent(dataObj);

						// debug rendering of tracks by playlist.
						if (tx_broadcastplaylist_pi1_debug == 1) {
							tx_broadcastplaylist_pi1_renderBroadcast(currentBroadcast, currentBroadcastImage);
						}
						tx_broadcastplaylist_pi1_renderTracks('byFeed');
					}
				}).get();
			} else {

				// render tracks - fallback:
				// no new signal, but we may need to update due to expired times
				tx_broadcastplaylist_pi1_renderTracks('fallback');
			}
		}
	}).get();


	// render broadcast:
	// check plausibility for the need of an update versus the schedule every full hour
	var currentHour = tx_broadcastplaylist_pi1_now.getHours();
	if (	tx_broadcastplaylist_pi1_lasttrackhour == 0 ||
		tx_broadcastplaylist_pi1_lasttrackhour != currentHour
	) {
		tx_broadcastplaylist_pi1_lasttrackhour = currentHour;
		// current hour different from last hour or not set. try to determine broadcast by schedule
		var jsonRequest3 = new Request.JSON({
			url: tx_broadcastplaylist_pi1_scheduleURL + dummyGP,
			method: 'get',
			onComplete: function(dataObj) {
				if (dataObj['exported']) {
					// get current broadcast from dataobj
					tx_broadcastplaylist_pi1_getBroadcast(dataObj);
				}
			}
		}).get();
	}
}





function tx_broadcastplaylist_pi1_tracksAreLive() {

	// out of order rule: handle this as live track in any case
	if (tx_broadcastplaylist_pi1_lasttracktstamp < 0) {
		return 1;
	}

	// normal handling: decide by offset time
	if ((tx_broadcastplaylist_pi1_lasttracktstamp + tx_broadcastplaylist_pi1_maxOffsetTime * 1000) >= tx_broadcastplaylist_pi1_now.getTime()) {
		return 1;
	} else {
		tx_broadcastplaylist_pi1_isInFallBackMode == 1;
		return 0;
	}
}





/*** get broadcast ***/

function tx_broadcastplaylist_pi1_getBroadcast(dataObj) {

	// travers all items to find the corresponding broadcast
	for(var item in dataObj) {
		if (typeof(dataObj[item]) == 'object') {

			// days match?
			var today = tx_broadcastplaylist_pi1_now.getDay();
			if (	today == dataObj[item]['weekday'] || 
				(today == 0 && dataObj[item]['weekday'] == 7)
			) {
//alert ('hour:' + tx_broadcastplaylist_pi1_now.getHours() + 'compared to' + dataObj[item]['broadcast_start']/3600);
				// does the time match (i.e. minutes of now is greater equal than the item)?
				var minutes = tx_broadcastplaylist_pi1_now.getHours() * 60 + tx_broadcastplaylist_pi1_now.getMinutes();
				if (minutes >= Math.floor(dataObj[item]['broadcast_start']/60)) {
					// broadcast ist found.
					tx_broadcastplaylist_pi1_renderBroadcast(dataObj[item]['B_TITLE'], dataObj[item]['B_BANNER']);
					break;
				}
			}
		}
	}
}

/*** end broadcast ***/





/*** get list ***/

function tx_broadcastplaylist_pi1_getListContent(dataObj) {

	var currentBroadcast = '';
	var counter = 0;
	var listContent = '';
	var listData = '';

	// travers all items, put them into list
	for(var item in dataObj) {

		listData = '';
		if (typeof(dataObj[item]) == 'object') {

			// store the broadcast title and its image
			if (dataObj[item]['B_TITLE']) {
				currentBroadcast = dataObj[item]['B_TITLE'];
				currentBroadcastImage = dataObj[item]['B_BANNER'];
			}

			listData = tx_broadcastplaylist_pi1_getItemContent(dataObj[item]);
		
			if (listData != '' && tx_broadcastplaylist_pi1_list) {
				var listEl = new Element('li', {
					'html': listData,
					'class': 'tx_broadcastplaylist_pi1_item'
				});
				tx_broadcastplaylist_pi1_elementList[counter] = listEl;
				counter++;
			}
		}
	}
}



function  tx_broadcastplaylist_pi1_getItemContent(item) {
	var listData = '';

	// add track time
	if (item['T_START']) {
		theTime = new Date();
		theTime.setTime(item['T_START'] * 1000 + tx_broadcastplaylist_pi1_timezoneCorrection);
		var curr_min = theTime.getMinutes() + "";
		if (curr_min.length == 1) curr_min = "0" + curr_min;
		var curr_hour = theTime.getHours() + "";
		// store the current hour to global comparison var
		tx_broadcastplaylist_pi1_lasttrackhour = curr_hour;

		if (curr_hour.length == 1) curr_hour = "0" + curr_hour;

		// listData = listData + theTime.getHours() + ':' + theTime.getMinutes() + '(' + item['T_START'] + '|' + item['T_START_HR_HM'] + ')';
		// listData = listData + curr_hour + ':' + curr_min;
		listData = listData + '<div class="timedate">' + curr_hour + ':' + curr_min + '</div>';
	}

	listData = listData + '<div class="metadata">';

	// add track interpreter
	if (item['interpreter']) {
		// listData = listData + ' ' + item['interpreter'];
		listData = listData + ' <div class="interpreter">' + item['interpreter'] + '&nbsp;- </div>';
	} else if(item['composer']) {
		listData = listData + ' <div class="interpreter">' + item['composer'] + '&nbsp;- </div>';
	}

	// category switch
	switch (item['category']) {
		case tx_broadcastplaylist_pi1_catSpecial:

			// store the time to global comparison var (special value:-1)
			tx_broadcastplaylist_pi1_lasttracktstamp = -1;

			// add special text
			listData = listData + '<div class="title">' + tx_broadcastplaylist_pi1_catSpecialText + '</div>';

			break;
		default:

			// store the time to global comparison var
			tx_broadcastplaylist_pi1_lasttracktstamp = theTime.getTime();

			// add track title
			if (item['title']) {
				// listData = listData + ' - ' + item['title'];
				listData = listData + '<div class="title">' + item['title'] + '</div>';
			}
	}

	listData = listData + '</div>';
	return listData;
}

/*** end list ***/





/*** rendering ***/

function tx_broadcastplaylist_pi1_renderTracks (mode) {


	// possibilities for an update: 
	// 1) live update and tracks coming in by a feed (meaning: new tracks
	// 2) no live update (expired) and not yet in fallback mode
	
	if (	(tx_broadcastplaylist_pi1_tracksAreLive() == 1 && mode == 'byFeed' ||
		 tx_broadcastplaylist_pi1_tracksAreLive() == 0 && tx_broadcastplaylist_pi1_isInFallBackMode == 0)
	) {
		// rotate the existing items out of the way
		if($$('.tx_broadcastplaylist_pi1_item')) {
			tx_broadcastplaylist_pi1_list.innerHTML = '';
		}

		// fall back mode.
		if (tx_broadcastplaylist_pi1_tracksAreLive() == 0 && tx_broadcastplaylist_pi1_isInFallBackMode == 0) {
			tx_broadcastplaylist_pi1_isInFallBackMode = 1;
			var fallbackEl = new Element('li', {
				'html': tx_broadcastplaylist_pi1_fallbackTitle,
				'class': 'tx_broadcastplaylist_pi1_item'
			});
			var tracks = Array(fallbackEl);
		}
		if (tx_broadcastplaylist_pi1_tracksAreLive() == 1 && mode == 'byFeed') {
			var tracks = tx_broadcastplaylist_pi1_elementList;
		}

		// output the items
		for (var i = 0; i < tracks.length; i++) {
			listEl = tracks[i];
			tx_broadcastplaylist_pi1_list.grab(listEl);
			var fxSlideIn = new Fx.Slide(listEl, {duration: 250, mode: 'horizontal'});
			fxSlideIn.hide().slideIn.delay(10,fxSlideIn);
		}

		// maybe add a scrollbar? at least scroll to bottom of container div
		var scrollMe = new Fx.Scroll($(tx_broadcastplaylist_pi1_scrollId)).toBottom();
	}
}



function tx_broadcastplaylist_pi1_renderBroadcast(currentBroadcast, currentBroadcastImage) {

	// check plausibility on schedule
	var currentHour = tx_broadcastplaylist_pi1_now.getHours();
	if (tx_broadcastplaylist_pi1_lasttrackhour != currentHour) {
		return;
	}

	tx_broadcastplaylist_pi1_broadcast.innerHTML = tx_broadcastplaylist_pi1_broadcastPre + currentBroadcast;

	// update the image as well, if not set yet or different
	if (	tx_broadcastplaylist_pi1_image == '' ||
		tx_broadcastplaylist_pi1_image != currentBroadcastImage
	) {

		// check current image and pull the new image over it, if found
//			var pullOverMargin = 0;
		if (tx_broadcastplaylist_pi1_image != '') {
			var shownImageId = 'tx_broadcastplaylist_pi1_banner_' + tx_broadcastplaylist_pi1_image;
			$(shownImageId).dispose()
			/*
			pullOverMargin = -140; //$(shownImageId).getProperty('height');
			$(shownImageId).fade('in').get('tween').chain(function() {
				$(shownImageId).set('tween', { duration: 200 }).tween('opacity', 1, 0);
			}).chain(function() {
				$(shownImageId).dispose()
			});
			*/
		}

		// build new image and fade it in
		var imgEl = new Element ('img', {
			'src'	: tx_broadcastplaylist_pi1_bannerDir + currentBroadcastImage,
			'class'	: 'tx_broadcastplaylist_pi1_banner',
			'id'	: 'tx_broadcastplaylist_pi1_banner_' + currentBroadcastImage,
			'alt'	: currentBroadcast,
			'opacity': 0
		});
		tx_broadcastplaylist_pi1_banner.grab(imgEl);
		imgEl.fade('out').get('tween').chain(function() {
			// imgEl.fade('show');
			imgEl.set('tween', { duration: 500 }).tween('opacity', 0.3, 1);
		});

		// store shown image for the next run
		tx_broadcastplaylist_pi1_image = currentBroadcastImage;
	}
}

/*** end rendering ***/
