// libnk-calendar-actions.js
//
// Creates an overlay tooltip for day events on the calendar located at:
// http://www.chromaonline.com/chroma/teachers
// Day Events are collected from an inline script generated by a modified
// eZpublish CMS template, without this template the script will need
// modification to suit your needs.
//
// This script is a part of libnk; libnk is a personal library of classes
// -- created by me, Nathan Kelly -- that use the prototype.js and
// scriptaculous.js libraries. libnk scripts will not work without these two
// libraries.
//
// SOFTWARE NAME: libnk
// SOFTWARE RELEASE: 1.0
// COPYRIGHT NOTICE: Copyright (c) 2007 Nathan Kelly <info@nathan-kelly.com>
// SOFTWARE LICENSE: GNU General Public License v2.0
// NOTICE: >
// This program is free software; you can redistribute it and/or modify it under
// the terms of version 2.0 of the GNU General Public License as published by
// the Free Software Foundation.
// 
// This program 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.
// 
// You should have received a copy of version 2.0 of the GNU General Public
// License along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
//
// This script will not work without prototype.js or scriptaculous.js
// EACH OF THESE SCRIPTS ARE SUBJECT TO THEIR OWN LICENSE AGREEMENTS.
//

/////////////////////////////// START SCRIPT ///////////////////////////////////

// Define some Glabal vars
var activeEvent;
var PageSize;
var cellProperties;
var dayEvents = new Array;
var eventHTML = new Array;

// extend the Element object
Object.extend(Element, {
	getWidth: function(element) {
	   	element = $(element);
	   	return element.offsetWidth;
	},
	setWidth: function(element,w) {
	   	element = $(element);
    	element.style.width = w +"px";
	},
	setHeight: function(element,h) {
   		element = $(element);
    	element.style.height = h +"px";
	},
	setTop: function(element,t) {
	   	element = $(element);
    	element.style.top = t +"px";
	},
	setBottom: function(element,t) {
	   	element = $(element);
    	element.style.bottom = t +"px";
	},
	setLeft: function(element,t) {
	   	element = $(element);
    	element.style.left = t +"px";
	},
	setSrc: function(element,src) {
    	element = $(element);
    	element.src = src;
	},
	setHref: function(element,href) {
    	element = $(element);
    	element.href = href;
	},
	setInnerHTML: function(element,content) {
		element = $(element);
		element.innerHTML = content;
	}
});

// Create the CalendarActions class
var CalendarActions=Class.create();
CalendarActions.prototype={
	initialize: function( monthEvents, monthInfo ) {
		// if we dont have a list of monthEvents then
		// we need to kill the script right now.
		if (!monthEvents || monthEvents == '') return false;
		// if we do, then we can move on
		var dayEvents = document.getElementsByClassName( 'day-event' );
		for (var i=0; i<dayEvents.length; i++) {
			var dayEvent = dayEvents[i];
			dayEvent.href = '#';
			dayEvent.onclick = function() {
				// if the event-box element already exists close it
				if ($('event-box')) {
					myCalendarActions.closeEventBox();
				}
				// move on
				myCalendarActions.displayEvent( this, monthEvents, monthInfo );
				return false;
			}
		}

// -----------------------------------------------------------------------------
// Here is the HTML output we are going to create for the overlay tooltip.

//<div class="event-box-open" style="top: ?px; left: ?px;" id="event-box">
//	<div id="event-wrap">
//		<div id="event-box-count">
//			<p>There ? <strong>(?)</strong> event? on ? ? ?</p>
//		</div>
//		<div class="day-?" id="event-content">
//			<div id="day-number">
//				<strong>?</strong><span>? ?</span>
//			</div>
//			<ul id="event-list">
//				<li id="event-item-?" class="event-item">
//					<h5><strong>?</strong><br><a href="?">?</a></h5>
//					<p class="event-date"><strong>From:</strong> ? <strong>To:</strong> ?</p>
//					<p><strong>Teacher:</strong> <a href="?">?</a></p>
//					<p><strong>Brands:</strong> ?. </p>
//					<p><strong>Techniques:</strong> ?. </p>
//					<p><strong>Painting Mediums:</strong> ?.</p>
//				</li>
//			</ul>
//		</div>
//	</div>
//	<div id="event-box-footer">
//		<a href="#" class="ui-button ui-button-close" id="close-event-box">Close</a>
//		<div id="event-box-nav">
//			<a style="" href="#" class="ui-button ui-button-next" id="next-event-button">Next Event</a>
//			<span style="display: none;" class="ui-button ui-button-next-disabled" id="next-event-button-disabled">Next Event</span>
//			<a style="" href="#" class="ui-button ui-button-previous" id="prev-event-button">Previous Event</a>
//			<span style="display: none;" class="ui-button ui-button-previous-disabled" id="prev-event-button-disabled">Previous Event</span>
//		</div>
//	</div>
//</div>

// -----------------------------------------------------------------------------
// Now we create the HTML above:
// event-box-count DIV and event-item-? LI are created later using setInnerHTML
// because we will need to generate their content from the inline arrays.
// The rest is created right here.

		var objBody = document.getElementsByTagName('body').item(0);
		// Event Box
		var eventBox = document.createElement('div');
		eventBox.setAttribute('id','event-box');
		objBody.appendChild(eventBox);

		// Event Box Content wrapper
		var eventContentWrap = document.createElement('div');
		eventContentWrap.setAttribute('id','event-wrap');
		eventBox.appendChild(eventContentWrap);

		// Event Box Event Count
		var eventCountContainer = document.createElement('div');
		eventCountContainer.setAttribute('id','event-box-count');
		eventContentWrap.appendChild(eventCountContainer);
		
		// Event Box Content
		var eventContent = document.createElement('div');
		eventContent.setAttribute('id','event-content');
		eventContentWrap.appendChild(eventContent);

		// Event Box Footer
		var eventFooter = document.createElement('div');
		eventFooter.setAttribute('id','event-box-footer');
		eventBox.appendChild(eventFooter);

		// Event Box Close Button
		var closeAnchor = document.createElement('a');
		closeAnchor.setAttribute('id','close-event-box');
		closeAnchor.className = 'ui-button ui-button-close';
		closeAnchor.setAttribute('href','#');
		eventFooter.appendChild(closeAnchor);
		Element.setInnerHTML('close-event-box', 'Close');

		// Event Box Nav
		var eventNav = document.createElement('div');
		eventNav.setAttribute('id','event-box-nav');
		eventFooter.appendChild(eventNav);

		// Next Button
		var nextButton = document.createElement('a');
		nextButton.setAttribute('id','next-event-button');
		nextButton.className = 'ui-button ui-button-next';
		nextButton.setAttribute('href','#');
		eventNav.appendChild(nextButton);
		Element.setInnerHTML('next-event-button', 'Next Event');

		// Next Button Disabled
		var nextButtonDis = document.createElement('span');
		nextButtonDis.setAttribute('id','next-event-button-disabled');
		nextButtonDis.className = 'ui-button ui-button-next-disabled';
		eventNav.appendChild(nextButtonDis);
		Element.setInnerHTML('next-event-button-disabled', 'Next Event');

		Element.hide('next-event-button-disabled');

		// Previous Button
		var prevButton = document.createElement('a');
		prevButton.setAttribute('id','prev-event-button');
		prevButton.className = 'ui-button ui-button-previous';
		prevButton.setAttribute('href','#');
		eventNav.appendChild(prevButton);
		Element.setInnerHTML('prev-event-button', 'Previous Event');

		// Previous Disabled
		var prevButtonDis = document.createElement('span');
		prevButtonDis.setAttribute('id','prev-event-button-disabled');
		prevButtonDis.className = 'ui-button ui-button-previous-disabled';
		eventNav.appendChild(prevButtonDis);
		Element.setInnerHTML('prev-event-button-disabled', 'Previous Event');

		Element.hide('prev-event-button-disabled');

		// Hide the event box and the next and previous buttons
		Element.hide('event-box');

		return false;
	},

	displayEvent: function( whichDay, monthEvents, monthInfo ) {
		// get the position of the cell we just clicked so we can
		// position the tooltip overlay relative to it
		cellProperties = getCellProperties( whichDay );
		// empty the day array
		dayArray = [];
		// set the day number (integer starting from 0)
		eventNum = 0;
		// create the day date, this is an enlarged version of the
		// calendar cell that is displayed beside the current event
		var startEventHTML = '<div id="day-number"><strong>' + cellProperties[4] + '</strong><span>' + monthInfo["monthAbbr"] + ' ' + monthInfo["year"] + '</span></div>';
		// create the event parent element (I'm using a ul because the
		// fallback method (js disabled) uses a list for the events this
		// saves some extra stylesheet work
		startEventHTML += '<ul id="event-list"></ul>';
		// set the day date and event parent HTML
		Element.setInnerHTML( 'event-content', startEventHTML );
		// the actual event count is different to the total event count
		// so we need to increment it seperately starting from 0
		var e = 0;
		// now loop through the monthEvents array, this is collected
		// from the inline script, generated by the page
		for(var i=0; i<monthEvents.length; i++) {
			var monthEvent = monthEvents[i];
			// get events who's id is the same as the day we clicked
			if (whichDay.id == monthEvent["id"]) {
				// add the details to the eventHTML array
				eventHTML[e] = '<li id="event-item-' + e + '" class="event-item">';
				eventHTML[e] += '<h5><strong>' + monthEvent["category"] + '</strong><br /><a href="' + monthEvent["url"] + '">' + monthEvent["name"] + '</a></h5>';
				eventHTML[e] += '<p class="event-date"><strong>From:</strong> ' + monthEvent["from_date"] + ' <strong>To:</strong> ' + monthEvent["to_date"] + '</p>';
				eventHTML[e] += '<p><strong>Teacher:</strong> <a href="' + monthEvent["owner_url"] + '">' + monthEvent["owner"] + '</a></p>';
				if (monthEvent["brands"] != '' || monthEvent["techniques"] != '' || monthEvent["mediums"] != '') {
					if (monthEvent["brands"] != '') {
						eventHTML[e] += '<p><strong>Brands:</strong> ' + monthEvent["brands"] + '</p>';
					}
					if (monthEvent["techniques"] != '') {
						eventHTML[e] += '<p><strong>Painting Styles:</strong> ' + monthEvent["techniques"] + '</p>';
					}
					if (monthEvent["mediums"] != '' ) {
						eventHTML[e] += '<p><strong>Painting Mediums:</strong> ' + monthEvent["mediums"] + '</p>';
					}
				}
				eventHTML[e] += '</li>';
				// if this is the first click our active event
				// (currently viewing) should be the first one
				if (e < 1) { activeEvent = 0; }
				// append ore eventHTML to the dayAray, the day
				// array will contain only the events that fall
				// on the day we clicked, the rest are ignored
				dayArray.push(new Array(eventHTML[e]));
				// increment the actual event count
				e++;
			}
		}
		// add the active event (currently viewing) to the event-box
		myCalendarActions.changeEvent(activeEvent, dayArray);
		// close button action
		$('close-event-box').onclick = function() {
			myCalendarActions.closeEventBox();
			return false;
		}
		// done
		return false;
	},

	changeEvent: function(activeEvent, dayArray) {
		// hide the nav elements
		Element.hide('prev-event-button');
		Element.hide('next-event-button');
		Element.hide('prev-event-button-disabled');
		Element.hide('next-event-button-disabled');
		// create the event count content for the currently viewed day
		var eventCount = dayArray.length;
		var eventDate = monthInfo["month"] + ' ' + cellProperties[4] + ' ' + monthInfo["year"];
		var eventCountHTML = '<h5 class="result-info"><span>There ';
		// word the event count phrase properly according to the count
		// and the date, could be future or past
		if (eventCount > 1) {
			if (cellProperties[3][0] == 'day-past') {
				eventCountHTML += 'were <strong>(' + eventCount + ')</strong> events on ' + eventDate;
			} else {
				if (cellProperties[3][1] != '') {
					eventDate = cellProperties[3][1];
				}
				eventCountHTML += 'are <strong>(' + eventCount + ')</strong> events on ' + eventDate;
			}
		} else {
			if (cellProperties[3][0] == 'day-past') {
				eventCountHTML += 'was <strong>(' + eventCount + ')</strong> event on ' + eventDate;
			} else {
				if (cellProperties[3][1] != '') {
					eventDate = cellProperties[3][1];
				}
				eventCountHTML += 'is <strong>(' + eventCount + ')</strong> event on ' + eventDate;
			}
		}
		eventCountHTML += '</span></h5>';
		// set the event-box-count content
		Element.setInnerHTML( 'event-box-count', eventCountHTML );		
		// set the active event html
		var HTML = dayArray[activeEvent];
		Element.setInnerHTML( 'event-list', HTML );
		// before we display the event-box we will need to hide any select elements
		hideSelectBoxes();
		// need to show the event-box first to get the width and height
		Element.show('event-box');
		// now we need to resize the event-box to fit the content
		myCalendarActions.resizeEventBox(dayArray);
		// done
		return false;
	},

	resizeEventBox: function(dayArray) {
		// apply the class name of the element we clicked to the
		// event-box content block so we can match style rules
		$('event-content').className = cellProperties[3][0];
		// get some positions and dimentions
		var eventCellWidth = cellProperties[2];
		var eventBoxHeight = $('event-box').offsetHeight;
		var eventBoxWidth = $('event-box').offsetWidth;
		var eventBoxTop = cellProperties[1] - (eventBoxHeight - 5);
		// minus 11 for the follwing due to 1px border on cell
		var eventBoxLeft = cellProperties[0] - (eventBoxWidth - eventCellWidth - 11);
		// set top and left positions of the overlay tooltip
		Element.setTop('event-box', eventBoxTop);
		Element.setLeft('event-box', eventBoxLeft);
		// set the event-box to the open state
		$('event-box').className = 'event-box-open';
		// update the nav
		myCalendarActions.updateNav(dayArray);
		// done
		return false;
	},

	updateNav: function(dayArray) {
		// get the event we are currently viewing so we know which event
		// we have to close, there is only one so use the className
		var current = document.getElementsByClassName('event-item');
		// we need the id, should be event-item-(integer)
		current = current[0].id;
		// previous button action, check if we need it
		if (activeEvent != 0) {
			// we do so show it
			Element.show('prev-event-button');
			// now check if we need the next button
			if (activeEvent == (dayArray.length - 1)) {
				// we don't need it so switch it with the span
				Element.show('next-event-button-disabled');
			}
			// and if we click previous
			$('prev-event-button').onclick = function() {
				// hide the current event
				Element.hide(current);
				// and decrement the active event integer
				activeEvent--;
				// then change the event we are viewing to the
				// event the precedes it
				myCalendarActions.changeEvent(activeEvent, dayArray);
				// and stop there
				return false;
			}
		}
		// next button action, check if we need it
		if (activeEvent != (dayArray.length - 1)) {
			// we do so show it
			Element.show('next-event-button');
			// now check if we need the previous button
			if (activeEvent == 0) {
				// we don't need it so switch it with the span
				Element.show('prev-event-button-disabled');
			}
			// and if we click next		
			$('next-event-button').onclick = function() {
				// hide the current event
				Element.hide(current);
				// and increment the active event integer
				activeEvent++;
				// then change the event we are viewing to the
				// event the follows it
				myCalendarActions.changeEvent(activeEvent, dayArray);
				// and stop there
				return false;
			}
		}
	},

	closeEventBox: function() {
		// we have closed the event box so hide it
		Element.hide('event-box');
		// set the event box to the closed state
		$('event-box').className = 'event-box-closed';
		// show the select boxes again
		showSelectBoxes();
		// and we are done
		return false;
	}
};
// End  the CalendarActions class

// Start functions

// getCellProperties, gets the properties of the element we clicked so we can
// position and style the overlay tooltip relative to it
function getCellProperties( cellElement ) {
	// cellElement is actually the anchor tag but I'm just calling it cell
	var positionX = 0;
	var positionY = 0;
	var cellWidth = cellElement.offsetWidth;
	var cellType = cellElement.parentNode.className;
	var cellDay = new Array;	
	if (cellType == 'current') {
		cellType = 'day-future';
		cellDay.push(cellType, 'today');
	} else {
		cellDay.push(cellElement.parentNode.className, '');
	}	
	
	var cellValue = cellElement.firstChild.nodeValue;

	while ( cellElement != null ) {
		positionX += cellElement.offsetLeft;
		positionY += cellElement.offsetTop;
		cellElement = cellElement.offsetParent;
	}

	var cellPropertiesArray = new Array( positionX, positionY, cellWidth, cellDay, cellValue );
	return cellPropertiesArray;
}

// showSelectBoxes, shows all select boxes on the page if we previously hid them
function showSelectBoxes(){
	selects = document.getElementsByTagName("select");
	for (i = 0; i != selects.length; i++) {
		selects[i].style.visibility = "visible";
	}
}

// hideSelectBoxes, hides all select boxes on the page to stop them showing
// through our overlay tooltip
function hideSelectBoxes(){
	selects = document.getElementsByTagName("select");
	for (i = 0; i != selects.length; i++) {
		selects[i].style.visibility = "hidden";
	}
}

function initCalendarActions(){if(!document.getElementById('calendar')) return; myCalendarActions=new CalendarActions( monthEvents, monthInfo );};
Event.observe(window, 'load', initCalendarActions);
Event.observe(window,'unload', Event.unloadCache);

