/**
 * @fileoverview EasyGUI Standard Buttons Functions
 *
 * @author 		Gaetan Lauff	<glauff@plansoft.de>
 * @package 	js.widgets
 *
 * @version 	$Id: class.button.js 241 2007-02-06 11:00:54Z glauff $
*/
var EasyGUI_button = Class.create();

Object.extend( Object.extend( EasyGUI_button.prototype, EasyGUI_widget.prototype ),
{
	isPressed: false,
	
	render: function() 
	{
		this.type				= Element.getAttributeValue( this.element, 'type' );
		this.toolbarId 			= Element.getAttributeValue( this.element, 'toolbarid' );
		this.uploadId			= Element.getAttributeValue( this.element, 'uploadid' );
		this.overimg			= Element.getAttributeValue( this.element, 'buttonoverimage' );
		this.pressedimg 		= Element.getAttributeValue( this.element, 'buttonpressedimage' );
		this.inactiveimg 		= Element.getAttributeValue( this.element, 'buttoninactiveimage' );
		
		this.bgimg 				= Element.getStyle( this.element, 'background-image' );
		this.backgroundColor 	= Element.getStyle( this.element, 'background-color' );
		
		Event.observe( this.element, 'mouseover', this.onButtonOver.bindAsEventListener( this ) );
		Event.observe( this.element, 'mouseout', this.onButtonOut.bindAsEventListener( this ) );
		Event.observe( this.element, 'click', this.onButtonClick.bindAsEventListener( this ) );
		
		if ( this.type == 'datepicker' ) {
			this.dateSeparator 		= Element.getAttributeValue( this.element, 'dateseparator' );
			this.dateFormat 		= Element.getAttributeValue( this.element, 'dateformat' );
			this.dateField			= $( Element.getAttributeValue( this.element, 'datetargetfield' ) );
			
			this.actualMonthText	= Element.getAttributeValue( this.element, 'dateactualmonthtext', 'this month' );
			this.closeText			= Element.getAttributeValue( this.element, 'dateclosetext', 'close' );
			
			if ( isEmptyValue(this.element.className) ) {
				this.element.className = 'easygui-dp';
			}
			
			this.dpid = 'EasyGUI_DatePicker';
			this.idpid = 'EasyGUI_DatePickerIframe';
			
			this.element.onclick = function() { return false; };			
			var dateDays = Element.getAttributeValue( this.element, 'datedays' );
			this.dayArrayShort = (!dateDays) ? ['Su', 'Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa'] : Util.getJSObject( dateDays );
			var dateMonths = Element.getAttributeValue( this.element, 'datemonths' );
			this.monthArrayLong = (!dateMonths) ? ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'] : Util.getJSObject( dateMonths );
		}
		
		this.reset();
	},
	
	reset: function() {
		if (this.bgimg) {
			this.element.style.backgroundImage = this.bgimg;
		} else {
			if ( this.backgroundColor != '#ece9d8' ) {
				this.element.style.backgroundColor = this.backgroundColor;
			}
		}
		
		this.isPressed = false;
		this.element.blur();
	},
	
	pageMousedown: function( evt )
	{
		if ($( this.dpid ) ) {
			Element.hide( this.dpid );
			Element._hide( this.dpid );
	
			this.setIFrame();
		}
	},
	
	onButtonOver: function( evt ) {
		if ( this.overimg ) {
			this.element.style.backgroundImage = 'url(' + this.overimg + ')';
		}
	},
	
	onButtonOut: function( evt ) {
		if ( this.overimg && !this.isPressed) {
			this.reset();
		} else {
			if (this.pressedimg) {
				this.element.style.backgroundImage = 'url(' + this.pressedimg + ')';
			}
		}
	},
	
	onButtonClick: function( evt ) {
		if ( this.pressedimg ) {
			var allButtons = document.getElementsByTagName('button');
			
			for (var i=0; i < allButtons.length; i++) {
				var button = gui.getWidget( allButtons[i].id );
				
				if ( this.toolbarId && button.toolbarId && this != button) {
					if (this.toolbarId == button.toolbarId) {
						button.reset();
					}
				}
			}
			
			this.isPressed = true;
			this.element.style.backgroundImage = 'url(' + this.pressedimg + ')';
		}
		
		if ( this.type == 'upload' ) {
			ekUpload.call( this, this.element );
		}
			
		if ( this.type == 'submit' ) {
			ekSubmit( this.id );
		}
			
		if ( this.type == 'request' ) {
			ekRequest( this.id );
		}
		
		if ( this.type == 'datepicker') {
			this.drawDatePicker();
		}
	},
	
	drawDatePicker: function() 
	{
		var dt = this.getFieldDate( $F( this.dateField ) );
		
		if (!$( this.dpid ) ) {
			var newNode = document.createElement("div");
			newNode.setAttribute("id", this.dpid);
			newNode.setAttribute("class", this.getStyleDefinition( "div" ) );
			newNode.setAttribute("style", "visibility: hidden;");
			document.body.appendChild(newNode);
		}
		
		var pickerDiv = $( this.dpid);
		pickerDiv.style.position = "absolute";
		pickerDiv.style.left = this.getPageOffsetLeft() + 'px';
		pickerDiv.style.top =  this.getPageOffsetTop() + 'px';
		pickerDiv.style.visibility = (pickerDiv.style.visibility == "visible" ? "hidden" : "visible");
		pickerDiv.style.display = (pickerDiv.style.display == "block" ? "none" : "block");
		pickerDiv.style.zIndex = 10000;
		
		this.refreshDatePicker(dt.getFullYear(), dt.getMonth(), dt.getDate());
	},
	
	/**
	 * This is the function that actually draws the datepicker calendar.
	 *
	 * @param	{int}	year
	 * @param	{int}	month
	 * @param	{int}	day
	 * @returns void
	 * @private
	 */
	refreshDatePicker: function(year, month, day)
	{
		var thisDay = new Date();
		
		if ((month >= 0) && (year > 0)) {
			thisDay = new Date(year, month, 1);
		} else {
			day = thisDay.getDate();
			thisDay.setDate(1);
		}
		
		var crlf = "\r\n";
		
		var TABLE 			= "<table cols=7 class='" + this.getStyleDefinition('table') + "'>" + crlf;
		var xTABLE 			= "</table>" + crlf;
		var TR 				= "<tr class='" + this.getStyleDefinition('row') + "'>";
		var TR_title 		= "<tr class='" + this.getStyleDefinition('title-row') + "'>";
		var TR_days 		= "<tr class='" + this.getStyleDefinition( 'day-row') + "'>";
		var TR_todaybutton 	= "<tr class='" + this.getStyleDefinition( 'today-button-row' ) + "'>";
		var xTR 			= "</tr>" + crlf;
		var TD 				= "<td class='" + this.getStyleDefinition( 'cell') + "' onMouseOut='this.className=\""+ this.getStyleDefinition('cell') + "\";' onMouseOver=' this.className=\"" + this.getStyleDefinition( 'cell-hover') + "\";' ";    // leave this tag open, because we'll be adding an onClick event
		var TD_title 		= "<td colspan=5 class='" + this.getStyleDefinition( 'title-cell') + "'>";
		var TD_buttons 		= "<td class='" + this.getStyleDefinition( 'button-cell' ) + "'>";
		var TD_todaybutton 	= "<td colspan=7 nowrap=\"nowrap\" class='" + this.getStyleDefinition( 'today-button-cell' ) + "'>";
		var TD_days 		= "<td class='" + this.getStyleDefinition( 'day-cell' ) + "'>";
		var TD_selected 	= "<td class='" + this.getStyleDefinition( 'day-hl-cell' ) + "' onMouseOut='this.className=\"" + this.getStyleDefinition( 'day-hl-cell') + "\";' onMouseOver='this.className=\"" + this.getStyleDefinition( 'cell-hover' ) + "\";' ";    // leave this tag open, because we'll be adding an onClick event
		var xTD 			= "</td>" + crlf;
		var DIV_title 		= "<div class='" + this.getStyleDefinition( 'title-text' ) + "'>";
		var DIV_selected 	= "<div class='" + this.getStyleDefinition( 'day-hl' ) + "'>";
		var xDIV 			= "</div>";
		
		var html = TABLE;
		
		html += TR_title;
		html += TD_buttons + this.getButtonCode(thisDay, -1, "&lt;") + xTD;
		html += TD_title + DIV_title + this.monthArrayLong[ thisDay.getMonth()] + " " + thisDay.getFullYear() + xDIV + xTD;
		html += TD_buttons + this.getButtonCode(thisDay, 1, "&gt;") + xTD;
		html += xTR;
		
		html += TR_days;
		
		for(i = 0; i < this.dayArrayShort.length; i++) {
			html += TD_days + this.dayArrayShort[i] + xTD;
		}
			
		html += xTR;
		html += TR;
		
		for (i = 0; i < thisDay.getDay(); i++) {
			html += TD + "&nbsp;" + xTD;
		}
		
		// now, the days of the month
		do {
			dayNum = thisDay.getDate();
			TD_onclick = " onclick=\"dialog." + this.id + ".updateDateField('" + this.getDateString(thisDay) + "');\">";
		
			if (dayNum == day) {
				html += TD_selected + TD_onclick + DIV_selected + dayNum + xDIV + xTD;
			} else {
				html += TD + TD_onclick + dayNum + xTD;
			}
			
			if (thisDay.getDay() == 6) {
				html += xTR + TR;
			}
			
			thisDay.setDate(thisDay.getDate() + 1);
		} while (thisDay.getDate() > 1)
		
		if (thisDay.getDay() > 0) {
			for (i = 6; i > thisDay.getDay(); i--) {
				html += TD + "&nbsp;" + xTD;
			}
		}
		
		html += xTR;
	
		var today = new Date();
		html += TR_todaybutton + TD_todaybutton;
		html += "<button class='" + this.getStyleDefinition('today-button') + "' onClick='dialog." + this.id + ".refreshDatePicker();'>" + this.actualMonthText + "</button> ";
		html += "<button class='" + this.getStyleDefinition('today-button') + "' onClick='dialog." + this.id + ".updateDateField();'>" + this.closeText + "</button>";
		html += xTD + xTR;
	
		html += xTABLE;
		
		$(this.dpid).innerHTML = html;
		this.setIFrame();
	},
	
	/**
	 * This function updates the give date field
	 *
	 * @param	{string}	dateString
	 * @returns	void
	 * @private
	 */
	updateDateField: function( dateString )
	{
		if (dateString) {
			this.dateField.value = dateString;
		}
		
		Element.hide( this.dpid );
		Element._hide( this.dpid );
	
		this.setIFrame();
		this.dateField.focus();
	},
	
	/**
	 * Convert a JavaScript Date object to a string, based on the dateFormat and dateSeparator
	 * variables at the beginning of this script library.
	 * 
	 * @param	{object}	dateVal
	 * @returns	string
	 * @private
 	 */
	getDateString: function(dateVal)
	{
		var dayString 	= "00" + dateVal.getDate();
		var monthString = "00" + (dateVal.getMonth()+1);
		
		dayString 		= dayString.substring(dayString.length - 2);
		monthString 	= monthString.substring(monthString.length - 2);
		
		switch (this.dateFormat) {
			case "dmy" :
				return dayString + this.dateSeparator + monthString + this.dateSeparator + dateVal.getFullYear();
			case "ymd" :
				return dateVal.getFullYear() + this.dateSeparator + monthString + this.dateSeparator + dayString;
			case "mdy" :
			default :
				return monthString + this.dateSeparator + dayString + this.dateSeparator + dateVal.getFullYear();
		}
	},
	
	/**
	 * Convenience function for writing the code for the buttons that bring us back or forward
	 * a month.
	 *
	 * @param	{object}	dateVal
	 * @param	{int}		adjust
	 * @param	{string}	label
	 * @returns	{string}
	 * @private
	*/
	getButtonCode: function( dateVal, adjust, label )
	{
		var newMonth = (dateVal.getMonth () + adjust) % 12;
		var newYear = dateVal.getFullYear() + parseInt((dateVal.getMonth() + adjust) / 12);
		
		if (newMonth < 0) {
			newMonth += 12;
			newYear += -1;
		}
		
		return "<button class='" + this.getStyleDefinition( 'button' ) + "' onClick='dialog." + this.id + ".refreshDatePicker( " + newYear + ", " + newMonth + ");' style=\"width:20px\">" + label + "</button>";
	},
	
	/**
	 * Returns the formatted date for the field
	 *
	 * @param	{string}	dateString
	 * @returns	{string}
	 * @private
	 */
	getFieldDate: function(dateString)
	{
		var dateVal;
		var parts;
		var day, month, year;
		
		try {
			parts = DateTime.getParts( dateString, this.dateFormat );
			
			if (parts) {
				var day		= DateTime.getPart(parts, 'd', this.dateFormat);
				var month	= DateTime.getPart(parts, 'm', this.dateFormat);
				var year	= DateTime.getPart(parts, 'y', this.dateFormat);
				
				dateVal = new Date(year, month, day);
			} else if (dateString) {
				dateVal = new Date(dateString);
			} else {
				dateVal = new Date();
			}
		} catch(e) {
			dateVal = new Date();
		}
		
		return dateVal;
	},
	
	/**
	 * Draws an underlying iframe to fix ie select elements always being on top
	 *
	 */
	setIFrame: function()
	{
		if (is.ie5up) {
			var cal = $( this.dpid );
			
			if ( !cal.iframeEl ) {
				cal.iframeEl = cal.parentNode.insertBefore( Util.getIframe(), cal);
			}
			
			Element.setPosition( cal.iframeEl, cal.offsetTop, cal.offsetLeft );
			Element.show( cal.iframeEl );
			
			cal.iframeEl.style.position = 'absolute';
			cal.iframeEl.zIndex = parseInt( cal.style.zIndex ) - 1;
			
			Element.setDimension(cal.iframeEl, cal.clientWidth, cal.clientHeight);
			cal.iframeEl.style.display = cal.style.display;
			cal.iframeEl.style.visibility = cal.style.visibility;
		}
	},
	
	disable: function() {
		this.element.addClassName('disabled');
		this.element.disabled = true;
	},
	
	enable: function() {
		this.element.removeClassName('disabled');
		this.element.disabled = false;
	}
});