/**
 * @uses jquery.js
 * @uses go.js
 */

var gc = (function() {

    var gc = new (go.Class(null, {
        
        '__construct': (function() {
            this.registry = {};
        }),
        
        '__destruct': (function() {
            if (page) {
                page.destroy();
            }
            if (layout) {
                layout.destroy();
            }
        }),
        
        'setLayout': (function(props) {
            layout = new (go.Class(LayoutClass, props))(this);
        }),
        
        'getLayout': (function() {
            return layout;
        }),
        
        'setPage': (function(props) {
            page = new (go.Class(PageClass, props))(this);
        }),        
        
        'getPage': (function() {
            return page;
        }),      
        
        'appendHelper': (function(name, props) {
            var cl = go.Class(HelperClass, props);
            helpers[name] = (new cl(this));
        }),
        
        'getHelper': (function(name) {
            return helpers[name];
        }),
        
        'module': (function(name, props) {
            name = name.split(".");
            var cont = gc.mo;
            for (var i = 0; i < name.length - 1; i++) {
                if (!cont[name[i]]) {
                    cont[name[i]] = {};
                }
                cont = cont[name[i]];
            }
            cont[name[name.length - 1]] = props;
        }),
        
        'log': (function() {
            if (console && console.log) {
                console.log.apply(console, arguments);
            }
        }),
        
        'ajax': (function(options) {
            var aj = new AjaxRequest(this, options);
            aj.send();
        }),
        
        'import': (function(module) {
            var src = "/js/mo/" + module.replace(/\./g, "/") + ".js";
            document.write('<script type="text/javascript" src="' + src + '"></script>');
        }),
        
        'eoc': null
    }))();
    
    gc.mo = {};
    
    var page;
    var layout;
    var helpers = {};
    
    var ViewClass = go.Class(null, {
        '__construct': (function(gc) {
            this.gc = gc;
            this.init();
        }),
        
        '__destruct': (function() {
            this.done();
            this.gc = null;
        }),

        'init': (function() {}),
        
        'done': (function() {}),

        'run': (function() {}),
        
        'onload': (function() {}),
        
        'eoc': null        
    });
    
    var PageClass = go.Class(ViewClass, {});
    var LayoutClass = go.Class(ViewClass, {});
    var HelperClass = go.Class(ViewClass, {});
    
    var AjaxRequest = go.Class({
        
        '__construct': (function(gc, options) {
            if (!options.action) {
                throw "ajax-action, please";
            }
            this.gc = gc;
            this.options = options;
            this.makeUrl();
            this.makeHandlers();  
        }),
        
        'success': (function(response) {}),
        
        'error': (function(response) {}),
        
        'errorGC': (function(response) {}),
        
        'errorHTTP': (function(response) {}),
        
        'callError': (function(response) {
            if (response.errorType == "gc") {
                this.errorGC(response);
            } else if (response.errorType == "http") {
                this.errorHTTP(response);
            }
            this.error(response);
        }),
        
        'send': (function() {
            $.ajax({
                'url'      : this.url,
                'data'     : this.options.data,
                'dataType' : "xml",
                'type'     : (this.options.post ? "POST" : "GET"),
                'success'  : this.onSuccess,
                'error'    : this.onError
            });
        }),
        
        'makeUrl': (function() { // @todo
            var lang = this.gc.registry.lang;
            if ((!lang) || (lang == "ru")) {
                lang = "";
            } else {
                lang = lang + "/";
            }
            this.url = "/ajax/" + lang + this.options.action.replace(/:/g, "/") + "/";            
        }),
        
        'makeHandlers': (function() {
            var handlers = ["success", "error", "errorGC", "errorHTTP"];
            var len      = handlers.length;
            var options  = this.options;
            for (var i = 0; i < len; i++) {
                var name = handlers[i];
                var handler = options[name];
                if (handler) {
                    this[name] = handler;
                }
            }
        }),

        'onSuccess_bind': (function(data, textStatus, jqXHR) {
            var response = {
                'xhr'      : jqXHR,
                'httpCode' : jqXHR.status
            };
            var de = $(data.documentElement);
            response.ok = (de.find("status").text() == "ok");
            if (response.ok) {
                var data = de.find("data").text();
                if (data) {
                    response.result = $.parseJSON(data);
                }
                var html = de.find("html");
                if (html.length) {
                    response.html = html.text();
                }
                this.success(response);                
            } else {
                response.errorType = "gc";
                response.errorCode = de.find("errorcode").text();
                response.errorInfo = de.find("errorinfo").text();
                this.callError(response);
            }
        }),
        
        'onError_bind': (function(jqXHR, textStatus, errorThrown) {
            this.callError({
                'xhr'       : jqXHR,
                'ok'        : false,
                'httpCode'  : jqXHR.status,
                'errorType' : "http"
            });
        }),
        
        'eoc': null        
    });
    
    function onDOMLoad() {
        if (page) {
            page.run();
        }
        if (layout) {
            layout.run();
        }
        for (var k in helpers) {
            helpers[k].run();
        }
    }
    
    function onAllLoad() {
        if (page) {
            page.onload();
        }
        if (layout) {
            layout.onload();
        }                
        for (var k in helpers) {
            helpers[k].onload();
        }        
    }
    
    $(document).ready(function() {
        onDOMLoad();
        onAllLoad();
    });
    
    return gc;
})();

