var _AButtonOrTextareaHasFocus = false;

DefaultFormBehavior();

function DefaultFormBehavior()
{
    // Attempt to eliminate some of the flashing that might be caused when we
    // give focus to an element that is "below the fold" and immediately scroll
    // back to the top of the page.
    if (document.all)
        window.offscreenBuffering = true;

	//THIS IS BEING DISABLED SINCE DEFAULT SUBMIT BUTTON FUNCTIONALITY IS 
	//IMPLEMENTED BY ASP.NET AND AVAILABLE ON THE Page.HtmlForm object. 
    //if (DefaultSubmitButton == null)
    //    DefaultSubmitButton = GetFirstSubmitButton();
    _AButtonOrTextareaHasFocus = false;

    //EnableDefaultFormSubmissionBehavior();
    EnableAutoHighlightingBehavior();
    AttachAutoTabDelegates();
    if (!window.SuppressMoveFocusToFirstField)
        MoveFocusToFirstField();
}

function FindHiddenAncestor(element)
{
    var hidden = false;
    var ancestor = element;
    while (!hidden && ancestor != null)
    {
        if (ancestor.style.display == "none" || 
            ancestor.style.visibility == "hidden")
            {
                hidden = true;
                break;
            } // if 
        ancestor = ancestor.parentElement;
    } 
    return hidden;
}

// Utility function to give focus to the first form element the end user is 
// likely to use upon loading a page.
function MoveFocusToFirstField()
{
    var bFoundFirstEditableField = false;
    if (document.forms[0])
    { 
	// If this is being invoked after the initial page load, function
	// may have been called to restore field selection for an ASP.Net 
	// AJAX UpdatePanel.
	if (top.__lastFocus != null)
	{
		top.__lastFocus.focus();
		return;
	}

        for (var i=0; i<document.forms[0].elements.length; i++)
        {
            var element = document.forms[0].elements[i];
            var sElementType = element.type;
            var bElementDisabled = element.disabled;
            
            // Find the first editable field.
            if (!bElementDisabled &&
                sElementType != "hidden" &&
                sElementType != "reset" )
            {                
                var hidden = FindHiddenAncestor(element);
                
                if (!bFoundFirstEditableField && !hidden)
                {
                    bFoundFirstEditableField = true;
                    element.focus();
                }
                
                // Now keep looking for the first editable field that has
                // the InitialFocus="true" attribute.
                if (element["InitialFocus"] != null && !hidden)
                {
                    element.focus();
                    break;
                }
            }
        }
    }
}

/* Delegates */
function ButtonOrTextareaGotFocus (source, args)
{_AButtonOrTextareaHasFocus = true; return true;}

function ButtonOrTextareaLostFocus(source, args)
{_AButtonOrTextareaHasFocus = false; return true;}

function InputGotFocus(source, args)
{
	source.className += " Highlight";  return true;
	top.__lastFocus = source;
}

function InputLostFocus(source, args)
{
	source.className = source.className.replace(new RegExp(" Highlight\\b"), ""); return true;
	top.__lastFocus = null;
}

function PreventDoubleClick(source, args)
{
    if (source.submitted) return false;

    source.submitted = true;
    return true;
}

function StoreFocus(id)
{
    _Focus = id;
}

/* This function allows mutiple functions to be "wired up" 
as in a multicast delegate in .Net. The difference between 
Prepending vs. Appending is that a prepended function that 
returns false will short circuit all remaining functions 
wired-up to the event. It is important to understand that 
prepended function calls are executed in a LIFO sequence. */
function PrependDelegate(_event, _delegate)
{
    return function(args)
    {
        var bResult2 = true;
        var bResult1 = _delegate(this, args);
        if (typeof _event == "function" && bResult1 != false) 
        {bResult2 = _event(this, args);}
        
        if (bResult1 == false || bResult2 == false) return false;
        return true;
    }
}

/* This function allows mutiple functions to be "wired up" 
as in a multicast delegate in .Net. All functions are executed 
regardless of return value (in contrast with Prepend above). */
function AppendDelegate(_event, _delegate)
{
    return function(args)
    {
        var bResult1 = true;
        if (typeof _event == "function")
        {bResult1 = _event(this, args);}
        var bResult2 = _delegate(this, args);
        
        if (bResult1 == false || bResult2 == false) return false;
        return true;
    }
}

function GetFirstSubmitButton()
{
    if (document.forms[0])
    { 
        for (var i=0; i<document.forms[0].elements.length; i++)
        {
            var sElementType = document.forms[0].elements[i].type;
            var bElementDisabled = document.forms[0].elements[i].disabled;
            if (!bElementDisabled && sElementType == "submit")
            {
				var hidden = FindHiddenAncestor(document.forms[0].elements[i]);
				if (!hidden)
				{
                	document.forms[0].elements[i].focus();
                	return document.forms[0].elements[i];
				}
            }
        }
    }
    return null;
}
    
// Enable auto-highlight of text fields.
function EnableAutoHighlightingBehavior()
{
    var inputs = document.getElementsByTagName("INPUT");
    for (var i=0; i < inputs.length; i++) 
    {
        if (inputs[i].type != "text") continue;
        inputs[i].className += " HighlightFocus";
        
        // Enable auto-highlight in IE.
        if (!document.all) continue;
        
	    inputs[i].onfocus = AppendDelegate(inputs[i].onfocus, InputGotFocus);
	    inputs[i].onblur = AppendDelegate(inputs[i].onblur, InputLostFocus);
    }
}


// Enable form submission when the user presses the enter key.
function EnableDefaultFormSubmissionBehavior()
{
    var inputs = document.getElementsByTagName("INPUT");
    for (var i=0; i < inputs.length; i++) 
    {
        var element = inputs[i];
        var sElementType = element.type;
        var bElementDisabled = element.disabled;

        if (sElementType == "submit" ||
            sElementType == "reset" ||
            sElementType == "button" ||
            sElementType == "image")
        {
            element.onclick = PrependDelegate(element.onclick, PreventDoubleClick);
            element.onfocus = AppendDelegate(element.onfocus, ButtonOrTextareaGotFocus);
            element.onblur = AppendDelegate(element.onblur, ButtonOrTextareaLostFocus);
        }
    }
            
    inputs = document.getElementsByTagName("TEXTAREA");
    for (i=0; i < inputs.length; i++) 
    {
        var element = inputs[i];

        element.onfocus = AppendDelegate(element.onfocus, ButtonOrTextareaGotFocus);
        element.onblur = AppendDelegate(element.onblur, ButtonOrTextareaLostFocus);
    }

    window.scrollTo(0, 0);

    document.onkeydown = HandleDefaultFormSubmission;    
}


// If DefaultSubmitButton is defined, that button's click
// event will be fired. Otherwise form.submit() will be invoked.
function HandleDefaultFormSubmission(evt)
{
    var c = document.layers ? evt.which 
            : document.all ? event.keyCode
            : evt.keyCode;            
   
    if (_AButtonOrTextareaHasFocus || c != 13) return true;
    
    if (DefaultSubmitButton == null) 
        return document.forms[0].submit();

    return DefaultSubmitButton.click();
}

// According to: http://developer.mozilla.org/en/docs/DOM:element.click
// Only elements of type button, checkbox, radio, reset or submit implement
// the click() method.
function ClickElement(element)
{
    var evt = document.createEvent("MouseEvents");
    evt.initMouseEvent("click", true, true, window, 1, 1, 1, 1, 1, false, false, false, false, 0, null);
    element.dispatchEvent(evt);
}


// Locate the parent of an element
function FindParent(element, root)
{
    var result = null;
    for (var i = 0; i<root.childNodes.length; i++)
    {
        if (root.childNodes[i].id == element.id)
            return root;
        else if (root.childNodes[i].childNodes.length > 0) 
            result = FindParent(element, root.childNodes[i]);
        if (result != null)
            return result;
    }
}

// variables and methods for auto-tabbing on the custom controls

var downStrokeField;
function autojump(fieldName,nextFieldName,fakeMaxLength)
{
	var myForm=document.forms[document.forms.length - 1];
    
    if (myForm.elements[nextFieldName])
    {
	    var myField=myForm.elements[fieldName];
	    myField.nextField=myForm.elements[nextFieldName];

	    if (myField.maxLength == null)
	    myField.maxLength=fakeMaxLength;
        
	    myField.onkeydown=autojump_keyDown;
	    myField.onkeyup=autojump_keyUp;
	}
}

function autojump_keyDown()
{
//    var KeyID = (window.event) ? event.keyCode : e.keyCode;
//    if (KeyID == 9 && this.value.length == 0) 
//        window.event.returnValue = false;

	this.beforeLength=this.value.length;
	downStrokeField=this;
}

function autojump_keyUp()
{        
	if ((this == downStrokeField) && (this.value.length > this.beforeLength) && (this.value.length >= this.maxLength))
	{
		this.nextField.focus();
		this.nextField.select();
	}	
	downStrokeField=null;
}


// Utility function to attach auto-tab delegates to the common controls 
function AttachAutoTabDelegates()
{
    if (document.forms[0])
    { 
        for (var i=0; i<document.forms[0].elements.length; i++)
        {
            var element = document.forms[0].elements[i];
            
            // Find the first editable field.
            if (element.attributes["AutoTabField"])
            {          
        	    autojump(element.id, element.attributes["AutoTabField"].value, element.maxLength);          
            }
        }
    }
}