dojo.provide('max_ajax_base');
dojo.require('max_base');

function setInnerHTML(content, dom_node){
    function snarfScripts(cont, byRef){
        // summary
        //		strips out script tags from cont
        // invoke with 
        //	byRef = {errBack:function(){/*add your download error code here*/, downloadRemote: true(default false)}}
        //	byRef will have {code: 'jscode'} when this scope leaves
        byRef.code = "";
        
        function download(src){
            if (byRef.downloadRemote) {
                // console.debug('downloading',src);
                dojo.xhrGet({
                    url: src,
                    sync: true,
                    load: function(code){
                        byRef.code += code + ";";
                    },
                    error: byRef.errBack
                });
            }
        }
        
        // match <script>, <script type="text/..., but not <script type="dojo(/method)...
        return cont.replace(/<script\s*(?![^>]*type=['"]?dojo)(?:[^>]*?(?:src=(['"]?)([^>]*?)\1[^>]*)?)*>([\s\S]*?)<\/script>/gi, function(ignore, delim, src, code){
            if (src) {
                download(src);
            }
            else {
                byRef.code += code;
            }
            return "";
        });
    }
    
    function evalInGlobal(code, appendNode){
        // we do our own eval here as dojo.eval doesn't eval in global crossbrowser
        // This work X browser but but it relies on a DOM
        // plus it doesn't return anything, thats unrelevant here but not for dojo core
        appendNode = appendNode || dojo.doc.body;
        var n = appendNode.ownerDocument.createElement('script');
        n.type = "text/javascript";
        appendNode.appendChild(n);
        n.text = code; // DOM 1 says this should work
    }
    
    var code, byRef = {
        downloadRemote: true,
        errBack: function(e){
            alert('Error downloading remote script');
        }
    };
    
    content = snarfScripts(content, byRef);
    code = byRef.code;

    dom_node = dojo.byId(dom_node);
    dojo.query('[widgetId]', dom_node).forEach(function(n){
        dijit.byNode(n).destroy();
    });
    dom_node.innerHTML = content;
    try {
        dojo.parser.parse(dom_node);
    }catch(e){
        alert('Error when parsing dom_node' + e.message);
    }
    
    try {
        evalInGlobal(code, dom_node);
    } 
    catch (e) {
        alert('Error eval script: ' + e.message);
    }
    
}


/**
 * @author Max
 */
dojo.declare('max_ajax_base', max_base, {
    constructor: function(callUrl){
        this.url = callUrl;
        this.handleAs = "json";
        this.timeout = 20000; //Time in milliseconds
        this.dialogId = "form_dialog"
    },
    
    handleUpdateResponse: function(responseData, controllerName){
        errorUrl = url_root + controllerName;
        if (responseData.reloadHTTP) {
            // Probably first element or last element
            window.location = responseData.reloadHTTP;
        }else if (responseData.changeTableRow) {
            var row2change = dojo.byId(responseData.changeTableRow.html_element_id);
            if (row2change) {
                if (responseData.changeTableRow.noWipeOut) {
                    this.changeAnimation(row2change, responseData.changeTableRow.HTMLcontent).play();
                }
                else {
                    var wipeOutElement = "formDivElement";
                    if (responseData.changeTableRow.wipeOutElement) {
                        wipeOutElement = responseData.changeTableRow.wipeOutElement;
                    }
                    if (dojo.byId(wipeOutElement)){
                        this.wipeOutFlashAnimation(wipeOutElement, row2change, responseData.changeTableRow.HTMLcontent).play();
                    }else{
                        setInnerHTML(responseData.changeTableRow.HTMLcontent, row2change);
                    }
                    
                }
            }
            else {
                // Corrupt data
                window.location = errorUrl;
            }
        }else if (responseData.reloadTables) {
            for (key in responseData.reloadTables) {
                var table = dojo.byId(responseData.reloadTables[key].html_element_id);
                if (table) {
                    this.changeAndHideAnimation(table, table, responseData.reloadTables[key].HTMLcontent).play();
                }
                else {
                    // Corrupt data
                    window.location = errorUrl;
                }
            }
        } else {
            // False data
            window.location = errorUrl;
        }
    },
    
    changeAnimation: function(changeElementId, newContent){
        var changeElement = dojo.byId(changeElementId);
        if (!changeElement) {
            console.log('Could not find the changeElementId');
            console.log(changeElementId);
            return false;
        }
        var flashAnim = this.flashAnim(changeElement, "#E7E7FF", 2000);
        
        // Change content
        dojo.connect(flashAnim, 'beforeBegin', function(){
            setInnerHTML(newContent, changeElement);
        });
        dojo.connect(flashAnim, 'onEnd', this.accordionSizeAdapt);
        return flashAnim;
    },
    
    wipeOutFlashAnimation: function(removeElementId, newElementId, newContent){
        var removeDuration = 1000;
        
        dojo.require('dojo.fx');
        var removeElement = dojo.byId(removeElementId);
        if (!removeElement) {
            console.log('Could not find the removeElement');
            console.log(removeElementId);
            return false;
        }
        
        var removeAnim = dojo.fx.wipeOut({
            node: removeElement,
            duration: removeDuration
        });
        
        var newElement = dojo.byId(newElementId);
        if (!newElement) {
            console.log('Could not find the newElementId');
            console.log(newElementId);
            return false;
        }
        var flashAnim = this.flashAnim(newElement, "#E7E7FF", 2000);
        
        dojo.style(removeElement, 'overflow', 'hidden');
        // Change content
        dojo.connect(removeAnim, 'onEnd', function(){
            setInnerHTML(newContent, newElement);
        });
        dojo.connect(removeAnim, 'onEnd', this.accordionSizeAdapt);
        
        return dojo.fx.chain([removeAnim, flashAnim]);
    },
    
    wipeInFormDivContent: function(newElementId, newContent){
        dojo.require('dojo.fx');
        var newElement = dojo.byId(newElementId);
        if (!newElement) {
            console.log('Could not find the newElementId');
            console.log(newElementId);
            return false;
        }
        
        setInnerHTML(newContent, newElement);
        
        var newAnim = dojo.fx.wipeIn({
            node: newElement,
            duration: 2000
        });
		
        dojo.connect(newAnim, 'onEnd', this.accordionSizeAdapt);
        return newAnim;
    },
    
    accordionSizeAdapt: function(){
        var accordion = dijit.byId('customer_overview');
        if (accordion && accordion.resize) {
            accordion.resize();
        }
    },
    
    changeAndHideAnimation: function(removeElementId, newElementId, newContent){
        var removeDuration = 1000;
        var showDuration = 2000;
        
        dojo.require('dojo.fx');
        var newElement = dojo.byId(newElementId);
        if (!newElement) {
            console.log('Could not find the newElement');
            console.log(newElementId);
            return false;
        }
        var newAnim = dojo.fx.wipeIn({
            node: newElement,
            duration: showDuration
        });
        
        dojo.style(newElement, 'overflow', 'hidden');
        
        var removeElement = dojo.byId(removeElementId);
        if (removeElement) {
            var size = dojo.coords(removeElement);
            if (size.h < 80){
                removeDuration = 300;
            }

            var removeAnim = dojo.fx.wipeOut({
                node: removeElement,
                duration: removeDuration
            });
            
            dojo.style(removeElement, 'overflow', 'hidden');
            if (newContent != null) {
                dojo.connect(removeAnim, 'onEnd', function(){
                    setInnerHTML(newContent, newElement);
                });
            }
            
            var complex_anim = dojo.fx.chain([removeAnim, newAnim]);
            dojo.connect(complex_anim, 'onEnd', this.accordionSizeAdapt);

            return complex_anim;
        } else {
            if (newContent != null) {
                dojo.connect(newAnim, 'onEnd', function(){
                    setInnerHTML(newContent, newElement);
                });
            }
            setInnerHTML(newContent, newElement);
            dojo.connect(newAnim, 'onEnd', this.accordionSizeAdapt);
			
            return newAnim;
        }
    },
    
    changeContentPane: function(changeElementId, newContent){
        dojo.require('dojo.fx');
        var changeElement = dojo.byId(changeElementId);
        if (!changeElement) {
            console.log('Could not find the changeElement');
            console.log(changeElementId);
            return false;
        }
        
        dojo.style(changeElementId, 'overflow', 'hidden');
        
        var flashAnim = this.flashAnim('customer_data_div', "#FFFF00", 1000);
        
        dojo.style(changeElement, 'overflow', 'hidden');
        if (newContent != null) {
            dojo.connect(flashAnim, 'beforeBegin', function(){
                dijit.byId(changeElementId).attr('content', newContent);
            });
            dojo.connect(flashAnim, 'onEnd', this.accordionSizeAdapt);
            
            dojo.connect(flashAnim, 'onEnd', this.attachFormDivs);
        }
        
        return flashAnim;
    //dojo.fx.chain([removeAnim, newAnim, flashAnim]);
    },
    
    changeAndEraseAnimation: function(removeElement, showElement){
        dojo.require('dojo.fx');
        var out = dojo.fx.wipeOut({
            node: removeElement,
            duration: 200
        });
        var wIn = dojo.fx.wipeIn({
            node: showElement,
            duration: 200
        });
        var chain = dojo.fx.chain([out, wIn]);
        dojo.connect(chain, 'onEnd', function(){
            setInnerHTML('', removeElement);
        });
        dojo.connect(chain, 'onEnd', this.accordionSizeAdapt);
        return chain;
    },
    
    error: function(response, ioArgs){
        if (response.dojoType == "cancel") {
            //The request was canceled by some other JavaScript code.
            console.error('Cancelled request');
        }
        else 
        if (response.dojoType == "timeout") {
            console.error('Timeout for request');
        }
        else {
            //Some other error happened.
            console.error('Unknown error!');
            console.dir(response);
            console.error("HTTP status code: ", ioArgs.xhr.status);
        }
        return response;
    },
    
    attachForms2Validation: function(validatorType, form_name){
        if (validatorType != ''){
            var classEval = 'new max_validate_' + this.table_name + "." + validatorType + '("' + url_root + '")';
        }else{
            var classEval = 'new max_validate_' + this.table_name + '("' + url_root + '")';
        }
        
        // Add the submit lock
        var new_validating_form = dojo.byId(form_name);
        if (new_validating_form){
            new max_formValidator(new_validating_form, dojo.eval(classEval));
        }else{
            console.error('The form "' + new_validating_form + '" could not be found');
        }
    },

    _loadModules: function(){
        if(this.ajax_response.dojo_modules){
            dojo.forEach(this.ajax_response.dojo_modules,
                function(mod){
                    dojo.require(mod);
                });
        }
    },

    _loadActions: function(){
        if(this.ajax_response.dojo_actions){
            dojo.forEach(this.ajax_response.dojo_actions,
                function(action_code){
                    dojo.eval("fn = " + action_code);
                    dojo.addOnLoad(fn);
                });
        }
    },
});

dojo.declare('max_ajax_submitForm', max_ajax_base, {
    constructor: function(form){
        // Overwrites the max_ajax_base constructor which thinks form is an url
        this.url = form.action +
        (form.action.substring(form.action.lenght - 1) != '/' ? '/' : '') +
        'format/json';
        this.form = form.id;
    },
    
    _submitFormAjaxError: function(form, responseData){
        // Passed through the ordinary check
        if (responseData.id) {
            var textTrElement = this.table_name + "_row_" + responseData.id;
            var animation = this.wipeInFormDivContent(textTrElement, responseData.content);
            dojo.connect(animation, 'onEnd', this, function(){
                this.attachForms2Validation('edit');
            });
            animation.play();
            return responseData;
        }
        
        var nl = new dojo.NodeList(form);
        var el = dojo.query("#" + form.id + " input[type=submit]");
        if (!responseData.messages && responseData.token_error) {
            var html = '<h1 style="color: red">Critical error: ' + responseData.token_error;
            html += '</h1>';
            
            for (var i in el) {
                el[i].value = "X";
                el[i].disabled = true;
                el[i].addClassName('error');
                new dojo.NodeList(el[i]).addContent(html, 'after');
            }
        }
        else {
            console.error('Major unkown error! Tip! Add an alert after this to help readability.');
            console.log(responseData);
            for (var i in el) {
                el[i].disabled = false;
            }
        }
    },
    
    error: function(response, ioArgs){
        var nl = new dojo.NodeList(this.form);
        if (response.dojoType == "cancel") {
            //The request was canceled by some other JavaScript code.
            nl.addContent('<div id="form_ajax_error" class="critical_error"><h2 style="color: red">Request cancelled</h2><pre style="width: 20em;">' + response.toString() + '</pre></div>', 'after');
        }
        else 
        if (response.dojoType == "timeout") {
            //The request took over 5 seconds to complete.
            nl.addContent('<div id="form_ajax_error" class="critical_error"><h2 style="color: red">Time out</h2><pre style="width: 20em;">' + response.toString() + '</pre></div>', 'after');
        }
        else {
            //Some other error happened.
            nl.addContent('<div id="form_ajax_error" class="critical_error"><h2 style="color: red">Unknown error</h2><pre style="width: 20em;">' + response.toString() + '</pre></div>', 'after');
        }
        return response;
    },
    
    loadAdd: function(response, ioArgs){
        if (response.success) {
            this.changeAndEraseAnimation(this.add_new_div_id, this.add_new_header_id).play();
            if (response.newHttp) {
                // Probably first element
                window.location = errorUrl;
            }
            else {
                this.handleUpdateResponse(response, this.table_name);
            }
        }
        else {
            this._submitFormAjaxError(this.form, response);
        }
        return response;
    },
    
    loadEdit: function(response, ioArgs){
        if (response.success) {
            this.handleUpdateResponse(response, this.table_name);
        } else {
            this._submitFormAjaxError(this.form, response);
        }
        return response;
    }
});

dojo.declare('max_ajax_getForm', max_ajax_base, {

    loadEdit: function(response, ioArgs){
        this.ajax_response = response;
        this._loadModules();
        dojo.addOnLoad(this, "_loadEditForm");
        return response;
    },

    _loadEditForm: function() {
        var textTrElement = dojo.byId(this.table_name + "_row_" + this.ajax_response.id);
        var td_count = textTrElement.children.length;
        var td = dojo.create('td', {
            'colspan': td_count
        }, textTrElement);
        dojo.place(td, textTrElement, "only");
        setInnerHTML('<div id="formDivElement">' + this.ajax_response.form + '</div>', td);
        var form = dojo.byId(this.ajax_response.form_name);
        if (form){
            dojo.style(form, "width", "auto");
            dojo.style(form, "margin", "0px");
        }else{
            console.error("Form not found: " + this.ajax_response.form_name);
        }
        this.attachForms2Validation('edit', this.ajax_response.form_name);
    },
    
    loadAdd: function(response, ioArgs){
        this.ajax_response = response;
        this._loadModules();
        dojo.addOnLoad(this, "_loadAddForm");
        return response;
    },

    _loadAddForm: function () {
        var content = '<div id="formDivElement"><h2>' + this.ajax_response.title + "</h2>" + this.ajax_response.form + '</div>';
        var animation = this.changeAndHideAnimation(this.add_new_header_id, this.add_new_div_id, content);
        dojo.style(this.add_new_div_id, 'display', 'block');
        dojo.connect(animation, 'onEnd', this, function(){
            this.attachForms2Validation('add', this.ajax_response.form_name);
        });
        animation.play();
    }
});

dojo.declare('max_ajax_loadparts', max_ajax_base, {
    load: function(response, ioArgs){
        this.ajax_response = response;
        this._loadModules();
        this._loadActions();
        this.changeAnimation(response.element_id, response.content).play();
        return response;
    }
});


dojo.declare('max_tooltipdialog', null, {
    constructor: function(element_id){
        this.search_element = dijit.byId(element_id);
        if (!this.search_element){
            console.error("No search element found with id: " + element_id)
            return false;
        }

        var tooltip_id = element_id + '_search_results';
        this.tooltip = dijit.byId(tooltip_id);
        if (!this.tooltip){
            this.tooltip = new dijit.TooltipDialog({
                id: tooltip_id,
                content: 'Resultdialog'
            });

            this.tooltip.startup();

            dojo.connect(this.search_element, "onBlur", function(){
                dijit.popup.close(this.tooltip);
            });

        }


    },

    setSearchResults: function(results){
        if (results.length > 0){
            dijit.popup.open({
                parent: this.search_element,
                popup: this.tooltip,
                around: this.search_element
            });
            var new_content = "<b>Results</b><br />"
            dojo.forEach(response.matches, function(match){
                new_content += "<a href=\"" + match.url + "\">" + match.result + "</a><br />";
            });

            this.tooltip.setContent(new_content);
            this.search_element.focus();
        }else{
            this.tooltip.setContent("");
            dijit.popup.close(this.tooltip);
        }
    }
});

dojo.declare('max_ajax_show_search_results', max_ajax_base, {
    load: function(response, ioArgs){
        this.ajax_response = response;
        this._loadModules();

        var fieldset_element = dojo.byId("fieldset-" + response.fieldset_name);
        if (!fieldset_element){
            console.error("No field element found with id: fieldset-" + response.fieldset_name);
            return response;
        }
        
        
        var search_results_id = response.fieldset_name + '_search_results';
        var dd = dojo.byId(search_results_id);
        if (!dd){
            if (dojo.isFF){
                dd = dojo.create('dd', {id: search_results_id, style: "width: -moz-available; border: 1px #CCCCCC dashed; background-color: #FFFF99; padding: 0.5em;"});
            }else{
                dd = dojo.create('dd', {id: search_results_id, style: "width: 90%; border: 1px #CCCCCC dashed; background-color: #FFFF99; padding: 0.5em;"});
            }
            dojo.place(dd, fieldset_element, "last");
        }

        if (response.matches.length > 0){
            dd.innerHTML = response.content;
        }else{
            dojo.destroy(dd);
        }

        return response;
    }
});
