/* ===================================================================================================
* WARNING – This file is part of the base implementation for WebMaker, so it should not be edited or changed for any project. 
* These files are replaced if a project is re-imported to the WebMaker Studio or migrated to a new version of the product. 
* For guidance on ‘How do I override or clone Hyfinity webapp files such as CSS & javascript?’, please read the following relevant FAQ entry: 
* http://www.hyfinity.net/faq/index.php?solution_id=1113
==================================================================================================== */

/*
 * FMActions.js
 *
 * Provides implementations of the builtin actions provided by FormMaker
 *
 * @author Hyfinity Ltd
 * Copyright (c) 2009
 * @version 1.1
 *
 */


hyf.FMAction =
{
    version: '1.1',
    desc: 'Contains all the functions that implement the set of inbuilt FormMaker actions'
}

/**
 * Performs form submission
 * @param actionParam A param object containing the name of the action to submit to in the value property.
 * @param validateParam A param object indicating whether to validate before submission.  The value property
 *                  must contain true for validation to occurr.
 */
hyf.FMAction.handleFormSubmission = function(actionParam, validateParam)
{
    var fv = hyf.FMAction.getFormValidator();
    var f = fv.getForm();
    var action = f.action;
    if (actionParam != null && (typeof(actionParam) != 'undefined'))
    {
        action = actionParam.value + '.do';
    }

    if ((validateParam != null && (typeof(validateParam) != 'undefined') &&
        (validateParam.value == true) || (validateParam.value == 'true')))
    {
        if (hyf.validation.validateForm())
        {
            f.action = action;
            if (typeof(f.onsubmit) == 'function')
            {
                var resp = f.onsubmit();
                if ((typeof(resp) == 'boolean') && (resp == false))
                    return false;
            }
            f.submit();
            return true;
        }
        else
            return false;
    }
    else
    {
        f.action = action;
        if (typeof(f.onsubmit) == 'function')
        {
            var resp = f.onsubmit();
            if ((typeof(resp) == 'boolean') && (resp == false))
                return false;
        }
        f.submit();
        return true;
    }
}

/**
 * Performs an AJAX submission.
 * @param actionParam A param object indicating which action to call
 * @param sourceParam A param object indicating which source data to send to the remote service
 * @param targetParam A param object indicating which group the ajax response should be placed into.
 * @param validateParam a param object indicating whether to first validate the source. The value must be true for validation to occurr.
 */
hyf.FMAction.handleAjaxSubmission = function(actionParam, sourceParam, targetParam, validateParam, eventSourceParam)
{
    var targetGroup = targetParam.value;
    if ((typeof(targetParam.repeatId) != 'undefined') && (targetParam.repeatId != ''))
        targetGroup = targetParam.repeatId + targetGroup;

    var sourceGroup = null;
    if (sourceParam.option == 'PageGroup')
    {
        sourceGroup = sourceParam.value;
        if ((typeof(sourceParam.repeatId) != 'undefined') && (sourceParam.repeatId != ''))
            sourceGroup = sourceParam.repeatId + sourceGroup;
    }

    var functionPrefix = '';
    if (eventSourceParam.value)
        functionPrefix = eventSourceParam.value;


    if ((validateParam.value == true) || (validateParam.value == 'true'))
        hyf.FMAction.subSectionSubmit(actionParam.value, targetGroup, sourceGroup, functionPrefix, true);
    else
        hyf.FMAction.subSectionSubmit(actionParam.value, targetGroup, sourceGroup, functionPrefix, false);
}

/**
 * Sets the value of the specified field to the indicated value.
 * @param targetParam A param object indicating the field whose value should be changed.
 * @param valueParam A param object either containing the value to set, or specifiying which
 *                   field to get the new value from.
 */
hyf.FMAction.handleSetValue = function(targetParam, valueParam)
{
    var targetId = targetParam.value;
    if ((typeof(targetParam.repeatId) != 'undefined') && (targetParam.repeatId != ''))
        targetId = targetParam.repeatId + targetId;

    var target = document.getElementById(targetId);
    if (target != null)
    {
        var newValue = null;
        if (valueParam.option == 'PageField')
        {
            var sourceId = valueParam.value;
            if ((typeof(valueParam.repeatId) != 'undefined') && (valueParam.repeatId != ''))
                sourceId = valueParam.repeatId + sourceId;

            var source = document.getElementById(sourceId);
            if (source != null)
            {
                //QUESTION: Do we need to handle any other ways of getting the value??
                if (typeof(source.value) != 'undefined')
                    newValue = source.value;
                else if (typeof(source.innerText) != 'undefined')
                    newValue = source.innerText;
                else if (typeof(source.textContent) != 'undefined')
                    newValue = source.textContent;
            }
        }
        else
            newValue = valueParam.value;

        if (newValue != null)
        {
            //QUESTION: Do we need to handle any other ways of setting the value??
            if (typeof(target.value) != 'undefined')
                target.value = newValue;
            else
                target.innerHTML = newValue;
        }
    }
}

/**
 * Toggles the visibility of the specified group.
 * @param groupParam A param object indicating which group should be toggled.
 * @param animateParam A param object specifying whether to animate the showing/hiding of the group.
 *                     This object's value property must be 'true' for animation to occur.
 */
hyf.FMAction.handleGroupToggle = function(groupParam, animateParam)
{
    var groupId = groupParam.value;
    if ((typeof(groupParam.repeatId) != 'undefined') && (groupParam.repeatId != ''))
        groupId = groupParam.repeatId + groupId;

    if (animateParam.value == 'true')
        hyf.util.toggleComponent(groupId, null, true);
    else
        hyf.util.toggleComponent(groupId, null, false);
}

/**
 * Evalautes the given custom script.
 * This is not used, as the script is just output directly into the generated function.
 * @param scriptParam A param object whose value property contains the javascript string to evalaute.
 */
hyf.FMAction.handleCustomScript = function(scriptParam)
{
    eval(scriptParam.value);
}

/**
 * Resets the form controls in the specific container.
 * @param containerParam A param object indicating the container whose controls should be reset.
 * @param modeParam A param object specifying which type of reset to perform.  The option property
 *                      of this object should be either 'reset' or 'clear'
 */
hyf.FMAction.handleContainerReset = function(containerParam, modeParam)
{
    var container = null;
    if (containerParam.option == 'Form')
        container = hyf.FMAction.getFormValidator().getForm();
    else
    {
        var contId = containerParam.value;
        if ((typeof(containerParam.repeatId) != 'undefined') && (containerParam.repeatId != ''))
            contId = containerParam.repeatId + contId;

        container = document.getElementById(contId);
    }

    hyf.util.resetContainer(container, modeParam.option);
}


/**
 * Returns the form validator object that should be used for all validation
 * functionality.
 * This currently assumes that there is only one form on the page that should be validated.
 * If needed, we can extend this to allow selection of which form should be validated, and
 * so return the correct validator object.
 * @return The hyf.validation.FormValidator object to use for validation.
 * @private
 */
hyf.FMAction.getFormValidator = function()
{
    if (typeof(hyf.FMAction.formValidator) == 'undefined')
    {
        var f;
        if (hyf.validation.config.form)
            f = hyf.validation.config.form;
        else
            f = document.forms[0];

        hyf.FMAction.formValidator = new hyf.validation.FormValidator(f);
    }

    return hyf.FMAction.formValidator;
}

/**
 * Returns the error display object that should be used for displaying any
 * validation errors
 * @return The hyf.validation.ErrorDisplay object to use for showing errors.
 * @private
 */
hyf.FMAction.getErrorDisplay = function()
{
    if (typeof(hyf.FMAction.errorDisplay) == 'undefined')
    {
        var dispMethod = 'none'
        if (typeof(hyf.validation.config.errorDisplayMethod) != 'undefined')
            dispMethod = hyf.validation.config.errorDisplayMethod;

        hyf.FMAction.errorDisplay = new hyf.validation.ErrorDisplay(dispMethod);

        if (typeof(hyf.validation.config.errorDisplayFieldStyle) != 'undefined')
            hyf.FMAction.errorDisplay.setFieldStyle(hyf.validation.config.errorDisplayFieldStyle);
        if (typeof(hyf.validation.config.errorDisplayFieldClass) != 'undefined')
            hyf.FMAction.errorDisplay.setFieldClass(hyf.validation.config.errorDisplayFieldClass);
        if (typeof(hyf.validation.config.errorDisplayMessageStyle) != 'undefined')
            hyf.FMAction.errorDisplay.setMessageStyle(hyf.validation.config.errorDisplayMessageStyle);
        if (typeof(hyf.validation.config.errorDisplayMessageClass) != 'undefined')
            hyf.FMAction.errorDisplay.setMessageClass(hyf.validation.config.errorDisplayMessageClass);
        if (typeof(hyf.validation.config.errorDisplayShowMessage) != 'undefined')
            hyf.FMAction.errorDisplay.setShowMessage(hyf.validation.config.errorDisplayShowMessage);
        if (typeof(hyf.validation.config.errorDisplayShowAlerts) != 'undefined')
            hyf.FMAction.errorDisplay.setShowAlerts(hyf.validation.config.errorDisplayShowAlerts);
        if (typeof(hyf.validation.config.errorDisplayValidationMode) != 'undefined')
            hyf.FMAction.errorDisplay.setValidationMode(hyf.validation.config.errorDisplayValidationMode);
        if (typeof(hyf.validation.config.errorDisplayMessageLocation) != 'undefined')
            hyf.FMAction.errorDisplay.setMessageLocation(hyf.validation.config.errorDisplayMessageLocation);
        if (typeof(hyf.validation.config.errorDisplayMessageString) != 'undefined')
            hyf.FMAction.errorDisplay.setMessageString(hyf.validation.config.errorDisplayMessageString);
    }

    return hyf.FMAction.errorDisplay;

}



/**
 * Main function used to handle any sub section submission functionality.
 * This is used to update part of the page by making an asynchronous call to the server for more data.
 *
 * @param URL The URL to call to retrieve the new information.
 * @param target The ID of the container in which to place the resulting HTML retrieved.
 * @param source (optional) The ID of a source container.  The contents of any input fields within this container
 *                  will be sent in the request to the remote service.
 *                  If this parameter is not present, the full details on the page will be submitted.
 * @param functionPrefix (optional) A string containing the prefix that will be used for all custom functions
 *                  related to this sub section submission.  The process will check for the presense of
 *                  three different functions that will be called if they exist:
 *                      <functionPrefix>ConfigureRequestParameters(requestParams)
 *                      <functionPrefix>SetLoadingMessage(message)
 *                      <functionPrefix>ManipulateResponse(response, successful)
 * @param validate (optional) A boolean field to indicate whether or not the data being submitted should be
 *                  first validated for compliance with the defined constraints.
 *                  If not provided, no validation will be performed.
 * @return A boolean value indicating whether or not the asynchronous call has been initiated.
 */
hyf.FMAction.subSectionSubmit = function(URL, target, source, functionPrefix, validate)
{
    if (typeof(dojo) == 'undefined')
    {
        alert('This functionality requires the dojo framework to be available');
        return false;
    }

    //check if we need to validate the data being sent
    if (validate)
    {
        //check if we need to validate a group or the whole page
        if ((typeof(source) == 'undefined') || (source == null) || (document.getElementById(source) == null))
        {
            if (!hyf.validation.validateForm())
                return false;
        }
        else
        {
            if (!hyf.validation.validateContainer(document.getElementById(source)))
                return false;
        }
    }

    var content;

    if ((typeof(source) == 'undefined') || source == null || document.getElementById(source) == null)
    {
        content = dojo.formToObject(hyf.FMAction.getFormValidator().getForm());
    }
    else
    {
        if (URL.indexOf('.do') != -1)
            content = hyf.util.encodeContainer(document.getElementById(source), URL.substring(0, URL.length - 3));
        else
            content = hyf.util.encodeContainer(document.getElementById(source));
    }

    var requestArgs = {
            url         :   URL,
            content     :   content,
            mimetype    :   "text/html",
            handleAs    :   "text"
            };

    //Add a hook for manipulation of the request args
    if (eval("window." + functionPrefix + 'ConfigureRequestParameters'))
        eval(functionPrefix + 'ConfigureRequestParameters(requestArgs)');

    requestArgs.handle = hyf.FMAction.subSectionHandler;
    requestArgs.hyfTarget = target;
    requestArgs.hyfFunctionPrefix = functionPrefix;

    //Display a loading message in the target container
    var loadingContent = '<span class="ajaxLoading">Loading...</span>';
    //check if the user has created a function to override this message
    if (eval("window." + functionPrefix + 'SetLoadingMessage'))
        eval('loadingContent = ' + functionPrefix + 'SetLoadingMessage(loadingContent)');

    //if the message is empty, don't change the display
    if (loadingContent != null)
        hyf.util.insertContent(document.getElementById(target), loadingContent);

    // dojo.io.bind(requestArgs); ash_change
    dojo.xhrPost(requestArgs);

    return true;
};



/**
 * Handler function called after each ajax call.
 * This is the method syntax required by dojo
 *
 * @param response The response object retreived.
 * @param ioArgs The request parameters array containing all the details used to inititate the request
 *
 * @private
 */
hyf.FMAction.subSectionHandler = function(response, ioArgs)
{

    var target = document.getElementById(ioArgs.args.hyfTarget);

    if(response instanceof Error)
    {
        //QUESTION: Do we want to pass the ioArgs object to the function?
        var content = "Unable to show details.  Please try again.";
        if (eval("window." + ioArgs.args.hyfFunctionPrefix + 'ManipulateResponse'))
            eval('content = ' + ioArgs.args.hyfFunctionPrefix + 'ManipulateResponse(content, false, response, ioArgs)');

        hyf.util.insertContent(target, content, true);
    }
    else
    {
        var content = response;
        //Add hook for manipulation of the response here (eg client side XSL)
        if (eval("window." + ioArgs.args.hyfFunctionPrefix + 'ManipulateResponse'))
            eval('content = ' + ioArgs.args.hyfFunctionPrefix + 'ManipulateResponse(content, true)');

        hyf.util.insertContent(target, content, true);
    }
};




//------------------------------------------------------------------------------------------------
// BizFlow specific events functionality
// QUESTION: Should this be put into a seperate file?
hyf.HSGAction = {};


hyf.HSGAction.handleWIHAction = function(actionParam)
{
    var functionName = actionParam.value;

    if (functionName != '')
    {
        try
        {
            var scriptToEval = 'basicWIHActionClient.' + functionName + '()';
            eval(scriptToEval);
        }
        catch (e)
        {
            //we ignore errors here, as the most likely cause is that the page is not actually 
            //being run within the WIH environment.
        }
    }
}


