/**
 * Layout jQuery Tools
 *
 * Extend jQuery with some functions for controlling the layout unobtrusively via Javascript; for instance,
 * stretching the page to fill the viewport, stretching elements to fill their containers.
 *
 * @package pmweb
 * @subpackage layout
 * @since 01/10/2007
 * @copyright Profitmaster Systems Ltd., www.profitmaster.co.uk
 * @author Pete Hurst, <peterh@profitmaster.co.uk>
 * @version $Id: PMWebExtensions.js 3188 2009-10-08 14:50:03Z phil $ v1.0.0.1
 */

/**
 * Either sets min-height in compatible browser, or justplain height in IE6.
 */
jQuery.fn.minHeight = function(height) {
	// Use min-height if other than M$
	if (jQuery.browser.msie && (parseInt(jQuery.browser.version)<7)) {
		$(this).css("height",height);
	}
	else {
		$(this).css("min-height",height);
	}
};
 
/**
 * Cause one element to fill the height of a target (containing) element
 * An offset can be supplied to subtract a certain number of pixels from the new height
 */
jQuery.fn.fillHeight = function(target,offset) {
	// Default no extra offset
	if (offset==undefined) offset = 0;
	// Calculate and set the height
	
	var thisOffset = $(this).offset();
	if (thisOffset!=undefined) {
		var newHeight = $(target).height()
			- (thisOffset.top - $(target).offset().top + offset);
		$(this).minHeight(newHeight);
	}
};

/**
 * Make an element fill the page
 *
 * This looks at the viewport height, and stretches the target element if it isn't already maxed
 */
jQuery.fn.fillPage = function(offset) {
	// Default no extra offset
	if (offset==undefined) offset = 0;
	// Define a function for setting the height
	var fillFunc = function(target,offset) {
		var maxHeight = $(window).height();
		var newHeight = maxHeight - $(target).offset().top - offset;
		// Now we're setting a min-height, it should always be set
	//	if (newHeight>$(target).height()) {
			$(target).minHeight(newHeight);
	//	}
	}
	// Immediately fill the height
	fillFunc(this,offset);
	// Attach the function to window resizing also
//	$(window).resize(function(){fillFunc(this,offset);});
};

/**
 * When applied to an input element, usually textbox or textarea, will capture the enter key
 * and cause it to submit the contained form. Alternately a form reference can be passed in as
 * a parameter and that form will be submitted instead. A button name can be supplied and this
 * will simulate that button being clicked. 
 */
jQuery.fn.enterKeySubmits = function(formRef,buttonName) {
	// Attach the key handler
	$(this).keypress(function(e){
		// Respond to enter key
		if (e.which==13) {
			// Get a form ref if not one already
			if (formRef==undefined) {
				formRef=this.form;
			}
			formRef.submit();
		}
	});
}

jQuery.fn.extend({
    
	/**
	 * Add a watermark to an input box, also can pass in the CSS class to use as a marker tag
	 */
    watermark : function(text,cssClass) {
        // Default CSS class
        if (cssClass==undefined) cssClass='hasWatermark';
        // Fill with text value if empty
        if (!($(this).attr('value')) || $(this).attr('value')==text) {
            $(this).not(cssClass).attr('value',text).addClass(cssClass);
        }
        // Attach focus event (hide text and remove class)
        $(this).focus(function(evt){
            // Only blank/remove if it still has the class
            $(this).filter('.'+cssClass).removeClass(cssClass).attr('value','');
        });
        // Blue event (replace text if still empty, add class)
        $(this).blur(function(evt){
            // Restore watermark if still blank
            if (!($(this).attr('value')) || $(this).attr('value')==text) {
                $(this).attr('value',text).addClass(cssClass);
            };
        });
        var save = this;
        // Prevent watermark text being passed when button is clicked 
        $("form").submit(function(evt){
        	if ($(save).hasClass(cssClass) && $(save).attr('value')==text) {
        		$(save).attr('value','');
        	}
        });
        
    },

    /**
     * Cause a button click to be simulated when the Enter key is pressed
     * 
     * Button must be in the same form as the target element
     * 
     * buttonName is name of button to be "clicked"
     */
    enterKeyClicks : function(buttonName) {
    	// Attach the key handler
    	this.keypress(function(e){
    		// Respond to enter key
    		if (e.which==13) {
    			$("*[name=" + buttonName + "]", this.form).click();
    			return false;
    		}
    	});
    }
    
});

/**
 * Make element(s) wide enough to contain all the sub-elements identified by
 * the given selector.  Width is set using CSS min-width property.
 */
jQuery.fn.extend({
	containWidth : function(selector) {
		// for each element to which the function is being applied
		$(this).each(function() {
			var widest = 0;
			// for each contained element identified by the selector
			$(this).find(selector).each(function() {
				width = $(this).outerWidth(true);
				if (width > widest) {
					widest = width;
				}
			});
			if (widest > 0) {
				$(this).css("min-width", "" + widest + "px");
			}
			
		});
	}
});

 
$.fn.restoreOpenyCloseys = function() {
	var i;
	
	for (i = 0; i < this.length; i++) {
		frame = this.eq(i);
		title = frame.children(".title").text();
		cookieName = "Frame_" + title;
		
		if (Get_Cookie(cookieName) == "closed") {
			frame.children(".inner").hide();
			frame.removeClass("openy").addClass("closey");
		} else {
			frame.removeClass("closey").addClass("openy");
		}
	}	
};

$.fn.toggleOpenyClosey = function() {
	frame = this.parent();
	inner = frame.children(".inner");
	title = this.text();
	cookieName = "Frame_" + title;
	
	if (frame.hasClass("closey")) {
		if (jQuery.browser.msie) {
			inner.show("fast");
		} else {
			inner.slideDown("fast");
		}
		frame.removeClass("closey").addClass("openy");
		Delete_Cookie(cookieName, "/", "");
	} else {
		inner.slideUp("fast");
		frame.removeClass("openy").addClass("closey");
		Set_Cookie(cookieName, "closed" , 1, "/", "", "");
	}
	
	// 22/01/09 pns
	// IE6 fix: hide and show any open openycloseys after this one
	// When IE6 opens or closes an openyclosey it also moves the content
	// of any following openycloseys.  We correct this by
	// closing and reopening them.
	// This fix was needed for Dowding's template.  The cause of the problem
	// is IE6-obscure, so might not be a problem with other templates.
	if (jQuery.browser.msie && (parseInt(jQuery.browser.version) < 7)) {
		frame.nextAll(".openy").children(".inner").hide();
		frame.nextAll(".openy").children(".inner").show("fast");
	}
	
	return false;
}

function Set_Cookie( name, value, expires, path, domain, secure ) 
{
	// set time, it's in milliseconds
	var today = new Date();
	today.setTime( today.getTime() );
	
	/*
	if the expires variable is set, make the correct 
	expires time, the current script below will set 
	it for x number of days, to make it for hours, 
	delete * 24, for minutes, delete * 60 * 24
	*/
	if ( expires ) {
		expires = expires * 1000 * 60 * 60 * 24;
	}
	var expires_date = new Date( today.getTime() + (expires) );
	
	document.cookie = name + "=" +escape( value ) +
	( ( expires ) ? ";expires=" + expires_date.toGMTString() : "" ) + 
	( ( path ) ? ";path=" + path : "" ) + 
	( ( domain ) ? ";domain=" + domain : "" ) +
	( ( secure ) ? ";secure" : "" );
}

function Get_Cookie( check_name ) {
	// first we'll split this cookie up into name/value pairs
	// note: document.cookie only returns name=value, not the other components
	var a_all_cookies = document.cookie.split( ';' );
	var a_temp_cookie = '';
	var cookie_name = '';
	var cookie_value = '';
	var b_cookie_found = false; // set boolean t/f default f
	
	for ( i = 0; i < a_all_cookies.length; i++ )
	{
		// now we'll split apart each name=value pair
		a_temp_cookie = a_all_cookies[i].split( '=' );
		
		
		// and trim left/right whitespace while we're at it
		cookie_name = a_temp_cookie[0].replace(/^\s+|\s+$/g, '');
	
		// if the extracted name matches passed check_name
		if ( cookie_name == check_name )
		{
			b_cookie_found = true;
			// we need to handle case where cookie has no value but exists (no = sign, that is):
			if ( a_temp_cookie.length > 1 )
			{
				cookie_value = unescape( a_temp_cookie[1].replace(/^\s+|\s+$/g, '') );
			}
			// note that in cases where cookie is initialized but no value, null is returned
			return cookie_value;
			break;
		}
		a_temp_cookie = null;
		cookie_name = '';
	}
	if ( !b_cookie_found )
	{
		return null;
	}
}

function Delete_Cookie( name, path, domain ) {
	if ( Get_Cookie( name ) ) {
		document.cookie = name + "=" +
		( ( path ) ? ";path=" + path : "") +
		( ( domain ) ? ";domain=" + domain : "" ) +
		";expires=Thu, 01-Jan-1970 00:00:01 GMT";
	}
}

var PMWeb = {

	lastFocus : null,
	
	/**
	 * Standard function to be called on page load to implement some PMWeb UI
	 * 
	 * Currently this gets called from a client's main.js but really we should be automatically running it.
	 */
	OnLoad : function() {
		$("input").focus(function(){
			PMWeb.lastFocus = this;
		});

		// The pmAutoFocus class is used to auto-focus an element.
		// Setting the AutoFocus property of a FormInput causes the pmAutoFocus
		// class to be added to the input.
		// Ideally we would like to select the content of the input.  This isn't
		// always possible (combo boxes, for instance) so we make sure at least
		// to set the focus.
		$(".pmAutoFocus").focus().select();

		// The pmAutoPostback class is used to cause a form to be POSTed when
		// a certain event occurs on an input.  In the case of select inputs,
		// the postback occurs when the value is changed.
		$('.pmAutoPostback').change(
			function() {
				this.form.submit();
			}
		);

		// Expand any pmFitGrids elements so they're wide enough for any data
		// grids they contain
		$('.pmFitGrids').containWidth('.dataGrid');
		
		// pmScrollPane class uses jScrollPane plugin to add scrollbar
		// NB This must be done before closing any containing pmOpenyClosey or the
		//    jScrollPane plugin will think all the dimensions are zero and mess up.
		$(".pmScrollPane").jScrollPane({showArrows:true, autoHeight:true});
				
		// The pmOpenyClosey class is used to allow the user to toggle a frame
		// open/closed and remember the state between sessions using Cookies
		$(".pmOpenyClosey .title").click(
			function() {
				$(this).toggleOpenyClosey();
			}
		);
		$(".pmOpenyClosey").restoreOpenyCloseys();

		//$('.pmFormSubmitOnEnter')
	},
	
	GetCurrentFocus : function() {
		return PMWeb.lastFocus;
	},

	SetCurrentFocus : function(elem) {
		if (elem) {
			$(elem).focus().select();
			PMWeb.lastFocus = elem;
		}
	}
};

$(function() {
	// Call PMWeb standard setup
	PMWeb.OnLoad();
});