/**
 * Description of formHandling.js
 *
 * @author Phil Sorrell
 * @version 5.0.7
 * 5.0.7    Fix for replacing forms
 * 5.0.6    Beginning to include SSL support
 * 5.0.5    Changed label for more fields to fit better in IE7
 *          Bit of a bug fix
 * 5.0.4    Added basic validation to radiogroups
 *          Added show/hide partially for select boxes by change event type
 * 5.0.3    Added code for custom expressions
 * 5.0.2    Added custom file upload scripts *TEST ON ALL FILE UPLOADS*
 * 5.0.1    Added datePicker to repeater field
 * 5.0.0    Add button class of button
 *          Fixed url validation
 */
addDOMLoadEvent(setupDatePicker);
addDOMLoadEvent(setupValidation);
addDOMLoadEvent(setupRepeater);
addDOMLoadEvent(setupAjaxUploader);
addDOMLoadEvent(setupSeoField);
addDOMLoadEvent(setupShowHideFields);
addDOMLoadEvent(setupfh4Notes);


function setupShowHideFields()
{
    var x = $$('.fhShowHide');
    for (var i=0; i < x.length; i++)
    {
        fieldId = $(x[i]).down(".fhShowHideField").identify();
        // check whether field needs to be hidden
        if ($(fieldId + '_showhidedefaultstate').getValue()=="hide")
            hideField($(fieldId));

        triggerFieldId = $(fieldId + '_showhidetrigger').getValue();

        if ($(fieldId + '_hidetrigger').getValue()!="")
        {
            $(triggerFieldId).insert({after: '<input type="hidden" class="showhideTriggerValue" value="' + $(fieldId + '_hidetrigger').getValue() + '">'});
            if ($(triggerFieldId).getValue()==$(fieldId + '_hidetrigger').getValue()) hideField($(fieldId));
            if ($(triggerFieldId).readAttribute("type")=="radio")
            {
                $(triggerFieldId).up('.fhField').select('input[type=radio]').each(function(s) {
                    Event.observe(s, 'click', function(e)     {
                        if ($(triggerFieldId).getValue()==this.up('.fhField').down('.showhideTriggerValue').getValue()) hideField($(fieldId));
                        showField($(fieldId));
                    }, false);
                });
            } else {
                Event.observe($(triggerFieldId), 'click', function(e)     {
                    if (this.getValue()==this.next(".showhideTriggerValue").getValue()) hideField($(fieldId));
                }, false);
            }
        } else if ($(fieldId + '_showtrigger').getValue()!="")
        {
            function createShowFunc (ref)
            {
                return function(s)
                {
                    Event.observe(s, 'click', function(e)     {
                        triggerFieldId = $(ref + '_showhidetrigger').getValue();
                        if ($(triggerFieldId).getValue()==$(ref + '_showtrigger').getValue()) showField($(ref));
                        else hideField($(ref));
                    }, false);
                }
            }

            $(triggerFieldId).insert({after: '<input type="hidden" class="showhideTriggerValue" value="' + $(fieldId + '_showtrigger').getValue() + '">'});
            if ($(triggerFieldId).getValue()==$(fieldId + '_showtrigger').getValue()) showField($(fieldId));

            if ($(triggerFieldId).readAttribute("type")=="radio")
            {

                $(triggerFieldId).up('.fhField').select('input[type=radio]').each(createShowFunc(fieldId));
            } else if ($(triggerFieldId).tagName == "SELECT") {
                Event.observe($(triggerFieldId), 'change', function(e)     {
                    if (this.getValue()==this.next(".showhideTriggerValue").getValue()) showField($(fieldId));
                    else hideField($(fieldId));
                }, false);
            } else {
                Event.observe($(triggerFieldId), 'click', function(e)     {
                    if (this.getValue()==this.next(".showhideTriggerValue").getValue()) showField($(fieldId));
                    else hideField($(fieldId));
                }, false);
            }
        }
    }
}

function hideField(x)
{
    var myField = new LiveValidation(x.identify());
    myField.disable();
    x.up(".fhShowHide").hide();
}

function showField(x)
{
    var myField = new LiveValidation(x.identify());
    myField.enable();
    addValidation(x);
    x.up(".fhShowHide").show();
}

function addFileUploader(x)
{
    if (x.hasClassName("fhAjaxImage")) fileType = "image";
    else fileType = "file";
    uploadFile = x.readAttribute('data-uploadfile');
    if (uploadFile=="") uploadFile = "upload.php";
    //if(x.readAttribute('data-ssl')!='1')
    new AjaxUpload(x.identify(), {action: uploadFile, name: 'ajaxFile', data: {type: fileType}, onSubmit: createSubmitFunc(x), onComplete: createCompleteFunc(x)});
    //else new qq.FileUploader({element: x.identify(), action: uploadFile, onSubmit: createSubmitFunc(x), onComplete: createCompleteFunc(x), params: {name: 'ajaxFile', data: {type: fileType}}});

    function createSubmitFunc (ref)
    {
        return function(file, extension)
        {
            extensions = ref.next(".fhUploadExtensions").value;
            regExpression = '^(' + extensions + ')$';
            var rx = new RegExp(regExpression);
            if (! (extension && rx.test(extension))){
                        // extension is not allowed
                        alert('Error: invalid file extension');
                        // cancel upload
                        return false;
            }
            var y = $$('.ajaxLoader');
            ref.insert({before: '<img class="ajaxLoader" src="projects/formHandling4/ajax-loader.gif">'});
            ref.hide();
        }
    }

    function createCompleteFunc (ref)
    {
        return function(file, response)
        {
            ref.previous(".ajaxLoader").remove();
            if (response!="") {
                ref.insert({before: '<span class="upload_valid upload_validation_message">' + file + ' loaded ok!</span>'});
                $$('.fhUploadValue').each(function(item){item.remove()});
                ref.insert({before: '<input class="fhUploadValue" type="hidden" name="' + ref.readAttribute('name') + '_uploaded" value="' + response + '">'})
                ref.addClassName("fhAjaxUploadLocked");
            } else {
                ref.show();
                ref.insert({after: '<span class="upload_invalid upload_validation_message">Problem loading file!</span>'})
            }
        }
    }
}

function setupAjaxUploader()
{
    var x = $$('.fhAjaxUpload');
    for (var i=0; i < x.length; i++)
    {
        addFileUploader($(x[i]));
    }
}

function checkFileUploadState()
{
    var y = $$('.ajaxLoader');
    if (y.length<1) return true; else {
        alert ("Waiting for file uploads to finish!");
        return false;
    }
}

function addDatePicker(s)
{
        timeFormat = s.getAttribute("data-jstimeformat");
        dateTimeFormat = s.getAttribute("data-jsdatetimeformat");
        dateFormat = s.getAttribute("data-jsdateformat");
        Control.DatePicker.Locale['en_UK'] = {
	timeFormat: timeFormat,
        dateTimeFormat: dateTimeFormat,
	dateFormat: dateFormat,
	firstWeekDay: 1,
	weekend: [0,6],
	language: 'en' };

        if (s.hasClassName("fhDate")) picker = new Control.DatePicker(s.identify(), {icon: 'projects/formHandling4/calendar.png', timePicker: false, locale: 'en_UK'});
        else if (s.hasClassName("fhDateTime")) picker = new Control.DatePicker(s.identify(), {icon: 'projects/formHandling4/calendar.png', timePicker: true, locale: 'en_UK'});
        else if (s.hasClassName("fhTime")) picker = new Control.DatePicker(s.identify(), {icon: 'projects/formHandling4/clock.png', datePicker: false, timePicker: true, locale: 'en_UK'});
        s.setStyle({cursor: 'pointer'});
}

function setupDatePicker ()
{
    var x = $$('.fhCalendar');

    for(var i=0; i < x.length; i++)
    {
        addDatePicker($(x[i]));
    }
}

/**
* Returns the value of the selected radio button in the radio group, null if
* none are selected, and false if the button group doesn't exist
*
* @param {radio Object} or {radio id} el
* OR
* @param {form Object} or {form id} el
* @param {radio group name} radioGroup
*/
function $RF(el, radioGroup) {
    if($(el).type && $(el).type.toLowerCase() == 'radio') {
        var radioGroup = $(el).name;
        var el = $(el).form;
    } else if ($(el).tagName.toLowerCase() != 'form') {
        return false;
    }

    var checked = $(el).getInputs('radio', radioGroup).find(
        function(re) {return re.checked;}
    );
    return (checked) ? $F(checked) : null;
}

function addRadioValidation(x)
{
    radioName = x.down(".fhJSValidation").readAttribute("name");
    formId = x.up("form").identify();
    if($RF(formId, radioName)!=false) {
        if ($RF(formId, radioName)!=null)
        {
            markRadioGroupOk(x);
        }

        y = x.select("input");
        for(var i=0;i<y.length;i++)
        {
            Event.observe($(y[i]), 'click', function(e)     {
                formId = this.up("form").identify();
                radioName = this.readAttribute("name");
                if ($RF(formId, radioName)!=null)
                {
                    markRadioGroupOk(this.up(".fhRadioGroup"));
                } else if ($RF(formId, radioName)!=false) {
                    markRadioGroupError(this.up(".fhRadioGroup"));
                }
            }, false);
        }
    }
}

function markRadioGroupOk(x)
{
    x.down(".fhField").addClassName("LV_valid_field");
    if(x.down("span.fhRequired")) x.down("span.fhRequired").hide();
}

function markRadioGroupError(x)
{
    x.down(".fhField").addClassName("LV_invalid_field");
    if (x.down("span.fhRequired")) x.down("span.fhRequired").show();
}

function addValidation(x) {
        fieldId = x.identify();
        if (x.hasClassName('fhJsFileUpload')!=true&&x.readAttribute("type")!="radio") {
            if (x.hasClassName("validate-password")) validMessage = '';
            else validMessage = '';
            var validation = new LiveValidation(fieldId, {validMessage: validMessage, onlyOnBlur: true});
            if (x.hasClassName("required")) {
                Event.observe(x, 'focus', function(e)     {
                        if(this.next("span.fhRequired")) this.next("span.fhRequired").hide();
                }, false);
                validation.add(Validate.Presence);
            }
            if (x.hasClassName("validate-int"))
                validation.add(Validate.Numericality, { onlyInteger: true });
            else if (x.hasClassName("validate-alphanum"))
                validation.add (Validate.Format, {pattern: /^[a-z 0-9A-Z][a-z A-Z0-9]*[a-z A-Z0-9]$/ });
            else if (x.hasClassName("validate-keywords"))
                validation.add (Validate.Format, {pattern: /[a-z A-Z]+(,{1}[A-Za-z ]+)*$/});
            else if (x.hasClassName("validate-name"))
                validation.add (Validate.Format, {pattern: /^[a-z A-Z][a-z A-Z\'\-]*[a-z A-Z]$/});
            else if (x.hasClassName("validate-custom")) {
                customPattern  =  new RegExp(x.readAttribute("data-customexpression"));
                validation.add (Validate.Format, {pattern: customPattern});
            }
            else if (x.hasClassName("validate-email"))
                validation.add (Validate.Email);
            else if (x.hasClassName("validate-alpha"))
                validation.add (Validate.Format, {pattern: /^[A-Za-z0-9\-\_]+$/});
            else if (x.hasClassName("validate-password")) {
                validation.add ( Validate.Length, { minimum: 6 } );
                validation.add (Validate.Format, {pattern: /[A-Za-z0-9\*\&\%\#\$\?\_\~\-]{6}[A-Za-z0-9\*\&\%\#\$\?\_\~\-]*$/});
            } else if (x.hasClassName("validate-comment"))
                validation.add (Validate.Format, {pattern: /[a-zA-Z0-9\.\,;:%£&#@!\^-_~`\"'\[\]\{\}\*\/\?\(\)]/});
            else if (x.hasClassName("validate-ukphone"))
                validation.add (Validate.Format, {pattern: /^[0\(][0-9 \)]+[0-9]$/});
            else if (x.hasClassName("validate-intphone"))
                validation.add (Validate.Format, {pattern: /^[0-9 ()+-.]+$/});
            else if (x.hasClassName("validate-number"))
                validation.add (Validate.Numericality);
            else if (x.hasClassName("validate-url"))
                validation.add (Validate.Format, {pattern: /^((http|https):\/\/)?[A-Za-z0-9]{2,}(\.{1}[A-Z-a-z0-9]{2,}){2,4}(\/{1}[A-Za-z0-9\/+!#=%&_.~?-]*)*$/});
            else if (x.hasClassName("validate-postcode"))
                validation.add (Validate.Format, {pattern: /^([A-PR-UWYZa-pr-uwyz]([0-9]{1,2}|([A-HK-Ya-hk-y][0-9]|[A-HK-Ya-hk-y][0-9]([0-9]|[ABEHMNPRV-Yabehmnprv-y]))|[0-9][A-HJKS-UWa-hjks-uw])\ {0,1}[0-9][ABD-HJLNP-UVW-Zabd-hjlnp-uvw-z]{2}|([Gg][Ii][Rr]\ 0[Aa][Aa])|([Ss][Aa][Nn]\ {0,1}[Tt][Aa]1)|([Bb][Ff][Pp][Oo]\ {0,1}([Cc]\/[Oo]\ )?[0-9]{1,4})|(([Aa][Ss][Cc][Nn]|[Bb][Bb][Nn][Dd]|[BFSbfs][Ii][Qq][Qq]|[Pp][Cc][Rr][Nn]|[Ss][Tt][Hh][Ll]|[Tt][Dd][Cc][Uu]|[Tt][Kk][Cc][Aa])\ {0,1}1[Zz][Zz]))$/});
            if (x.readAttribute("maxLength"))
                validation.add(Validate.Length, {maximum: x.readAttribute("maxLength")});
            if (x.readAttribute("minLength"))
                validation.add(Validate.Length, {minimum: x.readAttribute("minLength")});

            if (x.hasClassName("validate-inclusion"))
                validation.add(Validate.Inclusion, {within: [x.readAttribute("data-allowedvalues")], partialMatch: false, caseSensitive: false, failureMessage: 'Not Valid'});
        }
}

function setupValidation () {

    var x = $$('.fhJSValidation');
    for(var i=0; i < x.length; i++)
    {
        addValidation($(x[i]));
    }

    //add jsValidation to radio groups
    var z = $$('.fhRadioGroup');
    for (var m=0; m < z.length; m++)
    {
        addRadioValidation($(z[m]));
    }

    //turn off onSubmit if second button is clicked
    var y = $$('.fhSecondary');
    for(var n=0; n < y.length; n++)
    {
       Event.observe($(y[n]), 'click', function(e)     {
           this.up("form").setAttribute("onsubmit", "");
           this.insert({before: '<input type="hidden" name="' + this.getAttribute("name") + '" value="SET">'});
           this.up("form").submit();
       }, false);
    }
}

function setupSeoField() {
    var y = $$('.fhSeoEditable');
    for (var i=0; i < y.length; i++)
    {
        $(y[i]).insert({after: '<span class="fhSeoEdit"><img src="projects/centralIcons/edit-small.png" alt="Edit Field"></span>'});
        $(y[i]).next(".fhSeoEdit").setStyle({cursor: 'pointer'});
        Event.observe($(y[i]).next(".fhSeoEdit"), 'click', function(e)     {
            if (confirm("Are you sure you want to edit this field?"))
            {
                this.previous('.fhSeoEditable').enable();
                this.next('input').remove();
                this.remove();
            }
            Event.stop(e);
        }, false);
    }
}

function setupRepeater ()
{
    var x = $$('.fh4 .fhRepeaterCounter');

    for(var i=0; i < x.length; i++)
    {
        //insert add button - need to remove class
        maxCounterId = $(x[i]).down('input').identify() + '_max';

        if (parseInt($(maxCounterId).getValue()) > parseInt($(x[i]).down('input').getValue()))
        {
            $(x[i]).removeClassName('fhHidden');
            $(x[i]).down('.fhLabel').insert({top: '<input class="fhRepeaterButton button" value="Add Field" type="button">'});
            Event.observe($(x[i].down(".fhRepeaterButton")), 'click', function(e)     {
                //copy last field
                if (!this.up('.fhRepeaterCounter').previous('.fhHoldingElement').down('.ajaxLoader'))
                {
                    newField = this.up('.fhRepeaterCounter').previous('.fhHoldingElement').clone(true);
                    this.up('.fhRepeaterCounter').previous('.fhHoldingElement').insert({after: newField});
                    //ok field copied, now need to update all the ids and classes with new count
                    previousCount = parseInt(this.up('.fhHoldingElement').down('.fhField').down('input').getValue());
                    nextCount = previousCount + 1;
                    maxRequiredId = this.up('.fhHoldingElement').down('.fhField').down('input').identify() + '_required';
                    maxRequired = parseInt($(maxRequiredId).getValue());

                    this.up('.fhRepeaterCounter').previous('.fhHoldingElement').select('label').each(function(s){
                        s.innerHTML = s.innerHTML.replace(previousCount, nextCount);
                        s.writeAttribute('for', s.readAttribute('for').replace(previousCount, nextCount));
                    });

                    this.up('.fhRepeaterCounter').previous('.fhHoldingElement').select('input').each(function(s){
                        s.writeAttribute('name', s.readAttribute('name').replace(previousCount, nextCount));
                        s.writeAttribute('id', s.readAttribute('name').replace(previousCount, nextCount));
                        if (s.readAttribute('type')!='hidden') s.value = "";
                        if (s.next('.LV_validation_message')) s.next('.LV_validation_message').remove();
                        if (s.previous('.upload_validation_message')) s.previous('.upload_validation_message').remove();
                        s.removeClassName('LV_valid_field');
                        s.removeClassName('LV_invalid_field');
                        if (nextCount>maxRequired) {
                            s.removeClassName('required');
                            if (s.next(".fhRequired")) s.next(".fhRequired").remove();
                        }
                        if (s.hasClassName('fhUploadValue')) s.remove();
                        if (s.hasClassName('fhAjaxUploadLocked')) {
                            s.removeClassName('fhAjaxUploadLocked');
                            s.show();
                        }
                        if (s.hasClassName('fhAjaxUpload')) addFileUploader(s);
                        if (s.hasClassName('fhJSValidation')) addValidation(s);
                        if (s.hasClassName('fhCalendar')) {
                            //going to have to remove it from dom and rebuild it *sigh*
                            datajsdateformat = s.readAttribute('data-jsdateformat');
                            datajstimeformat = s.readAttribute('data-jstimeformat');
                            datajsdatetimeformat = s.readAttribute('data-jsdatetimeformat');
                            fieldname = s.readAttribute('name');
                            fieldid = s.readAttribute('id');
                            minlength = s.readAttribute('minlength');
                            maxlength = s.readAttribute('maxlength');
                            fieldclass = s.readAttribute('class');
                            fieldvalue = s.readAttribute('value');
                            s.insert({after: '<input data-jsdateformat="' + datajsdateformat + '" data-jstimeformat="' + datajstimeformat + '" data-jsdatetimeformat="' + datajsdatetimeformat + '" name="' + fieldname + '" minlength="' + minlength + '" maxlength="' + maxlength + '" class="' + fieldclass + '" type="text">'});
                            addDatePicker(s.next('input'));
                            if (s.next('input').hasClassName('fhJSValidation')) addValidation(s.next('input'));
                            s.remove();
                        }

                    });

                    if (this.up('.fhRepeaterCounter').previous('.fhHoldingElement').down('.fhImagePreview'))
                        this.up('.fhRepeaterCounter').previous('.fhHoldingElement').down('.fhImagePreview').remove();

                    if (this.up('.fhRepeaterCounter').previous('.fhHoldingElement').down('.fhFilePreview'))
                        this.up('.fhRepeaterCounter').previous('.fhHoldingElement').down('.fhFilePreview').remove();

                    if (this.up('.fhRepeaterCounter').previous('.fhHoldingElement').down('.fhUploadedFile'))
                        this.up('.fhRepeaterCounter').previous('.fhHoldingElement').down('.fhUploadedFile').remove();

                    if (this.up('.fhRepeaterCounter').previous('.fhHoldingElement').down('.fhFileDelete'))
                        this.up('.fhRepeaterCounter').previous('.fhHoldingElement').down('.fhFileDelete').remove();

                    this.up('.fhRepeaterCounter').previous('.fhHoldingElement').select('textarea').each(function(s){
                        s.writeAttribute('name', s.readAttribute('name').replace(previousCount, nextCount));
                        s.writeAttribute('id', s.readAttribute('name').replace(previousCount, nextCount));
                        s.innerHTML = "";
                        s.removeClassName('LV_valid_field');
                        s.removeClassName('LV_invalid_field');
                        if (nextCount>maxRequired) {
                            s.removeClassName('required');
                            if (s.next(".fhRequired")) s.next(".fhRequired").remove();
                        }
                        if (s.next('.LV_validation_message')) s.next('.LV_validation_message').remove();
                        if (s.hasClassName('fhJSValidation')) addValidation(s);
                    });

                    this.up('.fhRepeaterCounter').previous('.fhHoldingElement').select('select').each(function(s){
                        s.writeAttribute('name', s.readAttribute('name').replace(previousCount, nextCount));
                        s.writeAttribute('id', s.readAttribute('name').replace(previousCount, nextCount));
                        s.removeClassName('LV_valid_field');
                        s.removeClassName('LV_invalid_field');
                        if (nextCount>maxRequired) {
                            s.removeClassName('required');
                            if (s.next(".fhRequired")) s.next(".fhRequired").remove();
                        }
                        if (s.next('.LV_validation_message')) s.next('.LV_validation_message').remove();
                        if (s.hasClassName('fhJSValidation')) addValidation(s);
                    });

                    this.up('.fhHoldingElement').down('.fhField').down('input').value = nextCount;

                    maxCounterId = this.up('.fhHoldingElement').down('.fhField').down('input').identify() + '_max';
                    if ($(maxCounterId).getValue()<=nextCount) this.remove();

                } else {
                    alert ("Please wait until upload has finished.");
                }
            }, false);
        }
    }
}

function setupfh4Notes ()
{
    var y = $$('.fhNoteTrigger');
    for (var p=0; p < y.length; p++)
    {
        if ($(y[p]).hasClassName('fhHelpTriggerFancyZoom'))
        {
            if ($(y[p]).hasClassName('small')) helpWidth = 300;
            else if ($(y[p]).hasClassName('medium')) helpWidth = 450;
            else helpWidth = 600;
            $(y[p]).writeAttribute({href: "#" + $(y[p]).up(".fhHoldingElement").down('.fhField').down('.fhNote').identify()});
            new FancyZoom($(y[p]).identify(), {width: helpWidth});
            $(y[p]).style.visibility = "visible";
            $(y[p]).up(".fhHoldingElement").down('.fhField').down('.fhNote').hide();
        } else {
            Event.observe($(y[p]), 'click', function(e)     {
                this.up('.fhHoldingElement').down('.fhField').down('.fhNote').show();
                Event.stop(e);
            }, false);
            $(y[p]).style.visibility = "visible";

            $(y[p]).up('.fhHoldingElement').down('.fhField').down('.fhNote').hide();
        }
    }
}
