﻿function aqForm(form, action, page, onSuccess, extraParametersBuilder) {
    var f = {};

    f.form = form;
    f.action = action;
    f.page = page;
    f.extraParametersBuilder = extraParametersBuilder;

    f.declare = function() {
        $(f.form).validate();
        // Don't use "live" method: don't work in IE6/IE8 (sometimes)
        $(f.form).bind("submit", function() {
            if (!$(f.form).valid()) {
                //alert('Invalid form!');
                return false;
            }

            values = [];

            for (var i = 0; i < page.extraParametersBuilders.length; i++) {
                page.extraParametersBuilders[i](values);
            }


            values = values.concat($(this).formToArray());
            values.push({ name: 'aqservice', value: 'aqpull' });
            values.push({ name: 'aqid', value: f.action });

            if (f.extraParametersBuilder != null) {
                f.extraParametersBuilder(values);
            }

            $('body').css('cursor', 'progress');

            $.ajax({
                type: "POST",
                url: document.location.href,
                data: values,
                dataType: "xml",
                success: function(xml) {
                    var ok = page.serviceSuccess(xml);

                    if (onSuccess != null) {
                        onSuccess(ok);
                    }
                }
            });

            return false;
        });
    };

    return f;
};

function aqUpload(id, fileId, action, page, onSend, onSuccess) {
    var upload = {};

    upload.id = id;
    upload.fileId = fileId;
    upload.action = action;
    upload.page = page;

    upload.send = function() {
        /*
        prepareing ajax file upload
        url: the url of script file handling the uploaded files
        fileElementId: the file type of input element id and it will be the index of  $_FILES Array()
        dataType: it support json, xml
        secureuri:use secure protocol
        success: call back function when the ajax complete
        error: callback function when the ajax failed
        */
        var url = document.location.href;

        if (url.indexOf('?') >= 0) {
            url += "&";
        }
        else {
            url += "?";
        }

        url += "aqservice=aqupload&aqfileid=" + upload.fileId + "&aqfilename=" + $('#' + upload.id).val();

        for (var i = 0; i < page.extraParametersBuilders.length; i++) {
            var parameters = [];
            page.extraParametersBuilders[i](parameters);

            for (var j = 0; j < parameters.length; j++) {
                url += "&" + parameters[j].name + "=" + parameters[j].value;
            }
        }

        if (upload.action != null && upload.action != "") {
            url += "&aqid=" + upload.action;
        }

        if (onSend != null) {
            onSend();
        }

        $.ajaxFileUpload({
            url: url,
            secureuri: false,
            fileElementId: upload.id,
            dataType: 'xml',
            success: function(xml) {
                var ok = page.serviceSuccess(xml);

                if (onSuccess != null) {
                    onSuccess(ok);
                }
            }
        });
    };

    return upload;
};

function aqPage() {
    var page = {};

    page.rules = [];
    page.dynamicRules = [];
    page.forms = [];
    page.uploads = {};
    page.state = [];
    page.extraParametersBuilders = [];

    page.extraParametersBuilders.push(function(parameters) {
        for (var i = 0; i < page.state.length; i++) {
            parameters.push({ name: page.state[i].id, value: page.state[i].value });
        }
    });


    page.serviceSuccess = function(xml) {
        var success = $('result success', xml).text();

        var res = true;

        if (success != 'true') {
            alert($('result message', xml).text());
            res = false;
        }

        var redirection = $('redirection', xml).text();

        if (null != redirection && redirection.length > 0) {
            document.location = redirection;
            return false;
        }

        document.title = $('pageTitle', xml).text();

        page.state = [];

        $('client>state', xml).each(function(i, partElement) {
            page.state.push({ id: $(partElement).attr('id'), value: $(partElement).text() });
        });

        // Keep previous focus
        var focused = $(document.activeElement);

        $('part', xml).each(function(i, partElement) {
            var part = $(partElement);
            var text = part.text().replace('<!--[CDATA[', '').replace(']]-->', '');

            var node = $('#' + part.attr('id'));
            node.replaceWith(text);

            // Declare forms if necessary (live event isn't used)
            for (var f = 0; f < page.forms.length; f++) {
                if ($('#' + part.attr('id') + ' ' + page.forms[f].form).length > 0) {
                    //alert("declare form " + page.forms[f].form);
                    page.forms[f].declare();
                }
            }

            // Rules remains with "live" events
        });

        // Only apply dynamic rules on global content (no more root element)
        for (var i = 0; i < page.dynamicRules.length; i++) {
            page.dynamicRules[i]();
        }

        $('body').css('cursor', 'default');

        focused.focus();

        return res;
    };

    page.pull = function(action, parameters, onSuccess) {
        if (null == parameters) {
            parameters = [];
        }

        parameters.push({ name: 'aqservice', value: 'aqpull' });
        parameters.push({ name: 'aqid', value: action });

        for (var i = 0; i < page.extraParametersBuilders.length; i++) {
            page.extraParametersBuilders[i](parameters);
        }

        $('body').css('cursor', 'progress');

        $.ajax({
            type: "POST",
            url: document.location.href,
            data: parameters,
            dataType: "xml",
            success: function(xml) {
                var ok = page.serviceSuccess(xml);

                if (onSuccess != null) {
                    onSuccess(ok);
                }
            }
        });
    };

    $(document).ready(function() {
        // Declare forms
        for (var i = 0; i < page.forms.length; i++) {
            page.forms[i].declare();
        }

        // Apply rules
        for (var i = 0; i < page.rules.length; i++) {
            page.rules[i]();
        }

    });

    page.addRule = function(r) {
        page.rules.push(r);
    };

    page.addDynamicRule = function(r) {
        page.addRule(r);
        page.dynamicRules.push(r);
    }

    page.addForm = function(f) {
        var form = aqForm(f.form, f.action, page, f.onSuccess, f.extraParametersBuilder);
        page.forms.push(form);
    };

    page.addUpload = function(u) {
        page.uploads[u.id] = aqUpload(u.id, u.fileId, u.action, page, u.onSend, u.onSuccess);
    }

    return page;
}
