/*
 * Helpful functions
 */

function M_Prompt( Caption, Default )
{
	var Result = Default ? Default : new String();
	var First = Default ? true : false;

	while ( Result.trim().length == 0 || First )
	{
		First = false;

		Result = prompt(Caption, Result);
		if ( Result == null )
			return null;
	}

	return Result;
};

/*
 * Some element extensions
 */

Element.extend({
	Sortables: null,

	enable: function()
	{
		this.disabled = false;
		this.removeClass('Disabled');
	},

	disable: function()
	{
		this.disabled = true;
		this.addClass('Disabled');
	},

	processEnter: function( event, handler )
	{
		var ev = event || window.event;
		if (ev && (ev.which ? ev.which : ev.keyCode) == 13)
			handler();
	},

	isMouseOver: function( event )
	{
		var Position = this.getPosition();
		return event.page.x >= Position.left && event.page.x <= Position.right && 
			event.page.y >= Position.top && event.page.y <= Position.bottom
	},

	invisible: function()
	{
		this.addClass('Invisible');
	},

	visible: function()
	{
		this.removeClass('Invisible');
	},

	ProgressOn: function()
	{
		this.addClass('Progress');
	},

	ProgressOff: function()
	{
		this.removeClass('Progress');
	}
});

/*
 * Function extensions
 */

Function.extend({
	bindAsEnterHandler: function(bind){
		var fn = this;
		return function(event){
			var ev = event || window.event;
			if (ev && (ev.which ? ev.which : ev.keyCode) == 13)
				fn.call(bind);

			return true;
		};
	}
});

/*
 * Hotkey Selector
 */

var CHotkeySelector = new Class({
	Key: null,
	Modifiers: null,
	Function: Class.Empty,

	initialize: function( Key, Modifiers, Function )
	{
		this.Key = Key;
		this.Modifiers = Modifiers;
		this.Function = Function;
	}
});

/*
 * Common client-side form handler class
 */

 var CFormHandler = new Class({
	Assets: Class.Empty,
	ActiveSpinners: null,
	Locks: null,

	options: {
		ButtonBoxId: null,
		SpinnerBoxId: null,
		EnterHandler: null,
		EscapeHandler: null,
		assets: Class.empty,
		keymap: Class.empty
	},

	initialize: function(options)
	{
		this.setOptions(options);

		$(window).addEvent('keydown', this.HandlePageKeys.bind(this) );
		$(document).addEvent('keydown', this.HandlePageKeys.bind(this) );


		if ( this.options.assets != Class.empty )
		{
			this.Assets = new Hash();

			for (var key in this.options.assets)
			{
				if (this.options.assets[key][0] != "/")
					this.options.assets[key] = "/" + this.options.assets[key];
				
				new Asset.image(this.options.assets[key] );
				this.Assets.set( key, this.options.assets[key] );
			}
		}

		if ( this.options.keymap !== Class.empty )
		{
			this.KeyMap = [];

			for (var key in this.options.keymap)
			{
				var KeySets = key.split(',');
				KeySets.each(function(KeySet) {
					KeySet = KeySet.trim();
					var Parts = KeySet.split("+");
					if ( Parts.length )
					{
						this.KeyMap.include( new CHotkeySelector( Parts.getLast(), Parts.remove( Parts.getLast() ), this.options.keymap[key] ) );
					}
				}, this);
			}
		}

		this.Locks = new Hash();
		this.ActiveSpinners = new Hash;
	},

	fixFormHeight: function()
	{
		var HeightFix = $('HeightFix');
		if (HeightFix)
			HeightFix.style.height = '1px';
	},

	hideSaveSpinner: function(responseText)
	{
		var Spinner = $('Spinner');
		if (Spinner)
			Spinner.hide();

		if (this.options.ButtonBoxId != null)
			$(this.options.ButtonBoxId).show();
//			$ES('input',this.options.ButtonBoxId).each(function(input){input.disabled = false;})

		if (this.options.SpinnerBoxId != null)
			$(this.options.SpinnerBoxId).hide();
	},

	showButtonsSpinner: function()
	{
		if (this.options.ButtonBoxId != null)
			$(this.options.ButtonBoxId).hide();
//			$ES('input',this.options.ButtonBoxId).each(function(input){input.disabled = true;})

		if (this.options.SpinnerBoxId != null)
			$(this.options.SpinnerBoxId).show();
	},

	requestFailure: function()
	{
		alert(this.response.text.removeScripts());
	},

	completeRequest: function()
	{
		this.hideSaveSpinner();
		this.fixFormHeight();
	},

	displayError: function(message, elementId)
	{
		if ( !elementId )
			$('Message').innerHTML = "<span class=\"Message Error\">"+message+"</span>"
		else
			$(elementId).innerHTML = "<span class=\"Message Error\">"+message+"</span>"
	},

	showFailure: function( transport, elementId )
	{
		this.displayError(transport.response.text, transport.options.errorBlockId);
		this.hideSaveSpinner();
		this.fixFormHeight();
	},

	goToUrl: function( Url )
	{
		window.location = Url;
	},

	HandlePageKeys: function(event)
	{
		var event = new Event(event);

		if ( this.KeyMap !== Class.Empty )
		{
			this.KeyMap.each(function(Selector){
				if ( Selector.Key == event.key )
				{
					var ModifierFound = true;

					Selector.Modifiers.each(function(Modifier){
						if ( Modifier == 'alt' && !event.alt ) ModifierFound = false;
						if ( Modifier == 'meta' && !event.meta ) ModifierFound = false;
						if ( Modifier == 'control' && !event.control ) ModifierFound = false;
						if ( Modifier == 'shift' && !event.shift ) ModifierFound = false;
					})

					if ( ModifierFound )
					{
						event.stop();
						event.preventDefault();
						Selector.Function(event);
						return;
					}
				}
			});
		}
	},

	processPageKeys: function(event)
	{
		if (event.key == 'enter' && this.options.EnterHandler != null)
		{
			event.stop();
			$(this.options.EnterHandler).click();
			return true;
		}

		if (event.key == 'esc' && this.options.EscapeHandler != null)
		{
			event.stop();
			$(this.options.EscapeHandler).click();
			return true;
		}
		
		return false;
	},

	SetPage: function( Page, Handler, Update )
	{
		var PostBody = Object.toQueryString({PageIndex: Page});

		var Options = {handler:'ev{'+Handler+'}', 
							remote: 1,
							update: Update,
							evalScripts: true,
							onFailure: this.requestFailure,
							postBody: PostBody,
							postBodyOnly: true
						};

		new Phpr_Request(Options);
	},

	ShowSpinner: function( Name, Element, Asset, Options )
	{
		if ( !this.Assets || !this.Assets.get(Asset) )
			return;

		var ImageElement = document.createElement('img');
		$(ImageElement).setStyle( 'position', 'absolute' );
		$(ImageElement).setProperty( 'src', this.Assets.get(Asset) );
		$(ImageElement).setStyle( 'z-index', '10000' );

		var ElementSize = $(Element).getCoordinates();
		$(ImageElement).injectInside( 'Content' );
		var ImageSize = $(ImageElement).getCoordinates();

		var LeftOffset = 0;
		if ( $type(Options.LeftOffset) )
			LeftOffset = Options.LeftOffset;

		if ( !$type(Options.Left) )
			ImageElement.setStyle( 'left', ElementSize.width/2 + ElementSize.left - ImageSize.width/2 + LeftOffset );
		else
			ImageElement.setStyle( 'left', ElementSize.left + LeftOffset );

		ImageElement.setStyle( 'top', ElementSize.height/2 + ElementSize.top - ImageSize.height/2 );

		$(Element).setStyle( 'visibility', 'hidden' );
		this.ActiveSpinners.set( Name, {Spinner: ImageElement, SpinnerElement: $(Element)} );
	},

	HideSpinner: function( Name )
	{
		if ( this.ActiveSpinners.hasKey(Name) )
		{
			var Spinner = this.ActiveSpinners.get( Name );
			Spinner.Spinner.remove();
			Spinner.SpinnerElement.setStyle( 'visibility', 'visible' );
			this.ActiveSpinners.remove(Name);
		}
	},

	SetLock: function( Name )
	{
		this.Locks.set(Name, 1);
	},

	GetLock: function( Name )
	{
		return this.Locks.hasKey(Name);
	},

	RemoveLock: function( Name )
	{
		this.Locks.remove(Name);
	},

	ProgressOn: function()
	{
		$(document.body).ProgressOn();
	},

	ProgressOff: function()
	{
		$(document.body).ProgressOff();
	}
});

CFormHandler.implement(new Options);

/*
 * Event class extensions
 */

Event.implement({
	isFunctionalKey: function(){
		if (this.key == 'r' && this.control)
			return true;

		if (this.key == 'a' && this.control)
			return true;

		if (this.code >= 16 && this.code <= 20)
			return true;

		if (this.code >= 33 && this.code <= 40)
			return true;

		if (this.code >= 112 && this.code <= 123)
			return true;

		if (this.code == 144 || this.code == 145 || this.code == 20 || this.code == 93 || this.code == 27 )
			return true;

		return false
	},

	isCommandKey: function()
	{
		if (this.key == 'c' && this.control)
			return true;

		return false;
	}
});

/*
 * Modal box
 */

var ModalBox = new Class({
	Overlay: null,
	Contents: null,
	Visible: false,

	options: {
		onBeforeShow: Class.empty,
		onShow: Class.empty
	},

	initialize: function(options)
	{
		this.setOptions(options);

		this.Overlay = $('ModalBoxOverlay');
		this.Contents = $('ModalBoxContents');

		window.addEvent('resize', this.RecalcPositions.bind(this));
		window.addEvent('scroll', this.RecalcPositions.bind(this));
		window.addEvent('keydown', this.OnKey.bind(this));
		this.Overlay.addEvent('keydown', this.OnKey.bind(this));
	},

	Display: function()
	{
		if (this.Visible)
			return;

		this.fireEvent('onBeforeShow', [this.Contents]);
		this.Overlay.setOpacity(0.01);
		this.Overlay.show();
		this.Contents.show();
		this.Visible = true;

		var sizes = window.getSize();
		var startTop = sizes.scroll.y - this.Contents.offsetHeight;
		var endTop = sizes.scroll.y;

		this.RecalcPositions();
		this.fireEvent('onShow', [this.Contents]);
	},

	Hide: function()
	{
		this.Overlay.hide();
		this.Contents.hide();
		this.Visible = false;
	},

	OnKey: function(e)
	{
		if (!this.Visible)
			return;

		var e = new Event(e);
		switch (e.key)
		{
			case 'esc':  this.Hide(); break;
		}
	},

	RecalcPositions: function()
	{
		if (!this.Visible)
			return;

		var sizes = window.getSize();

		this.Overlay.setStyles({
			'left': sizes.scroll.x, 'top': sizes.scroll.y,
			'width': sizes.size.x, 'height': sizes.size.y});

		this.Contents.setStyles({
			'left': (sizes.scroll.x + (sizes.size.x - this.Contents.offsetWidth) / 2).toInt(),
			'top': (sizes.scroll.y).toInt()});
	}
});

ModalBox.implement(new Chain, new Events, new Options);

/**
 * Calendar functions
 */

function WoofooSelectDate(cal)
{
	var p = cal.params;
	var update = (cal.dateClicked || p.electric);
	var prefix = p.inputField.id.substring( 0, p.inputField.id.length - 9 );
	year = prefix + 'DateYear';
	day = prefix + 'DateDay';
	month = prefix + 'DateMonth';
	
	document.getElementById(month).value = cal.date.print('%m');
	document.getElementById(day).value = cal.date.print('%e');
	document.getElementById(year).value = cal.date.print('%Y');

	$(p.inputField.id).value = cal.date.print('%Y-%m-%d');

	if (cal.dateClicked)
		cal.callCloseHandler();
}

/*
 * Wufoo functions
 */

function WufooClearErrors()
{
	$ES('li.error').each(function(element){element.removeClass('error');});
}