var Settings = function(){};
Settings.ERROR_COLOR = "#BB0500";
Settings.FX_OUT_DURATION = 200;
Settings.FX_IN_DURATION = 200;

var SiteManager = new Class(
{
    trackPageView : function(page)
    {
        var pageTracker = _gat._getTracker("UA-3452763-1");
        pageTracker._setDomainName("none");
        //pageTracker._setVar("ajax");
        //pageTracker._setVar("ajax2");
        pageTracker._initData();
        pageTracker._trackPageview(page);    
    },
    
    showNormal: function()
    {
        var overlay  = $('overlay');
        var lightbox  = $('lightbox');
        
        if (overlay) overlay.dispose();
        if (lightbox) lightbox.dispose();
    },
    
    showLightBox: function(content)
    {
        var overlay  = new Element('div', {id: 'overlay'});
        var lightbox  = new Element('div', {id: 'lightbox'});
        lightbox.set('html', content);
        
        lightbox.inject($(document.body), 'top')
        overlay.inject($(document.body), 'top')
    },
    
    showWait: function()
    {
        var loadContent = '<center><img style="margin-top:100px" src="/media/images/icons/ajax-loader2.gif"></center>';
        this.showLightBox(loadContent);
    },

    loadContent : function(contentUrl, destination)
    {
        var siteManagerInstance = this;
        
        console.log('loadContent to ' + destination);
        
        var request = new Request(
            {
                url         : contentUrl,
                method      : "GET",
                evalScripts : false,
                evalResponse: false,
                async       : true, 
                onSuccess   : function(responseText, responseXml)
                {
                    siteManagerInstance.setContent(responseText, destination);
                }
            }
        );
        
        request.success = function(responseText, responseXml){ this.onSuccess(responseText, responseXml); }
        request.send();
    },
    
    setContent : function(content, destination)
    {
        console.log('setContent to ' + destination);
        
        if (!$(destination))
        {
            console.error('setContent: destination does not exist')
            return;
        }
        
        var siteManagerInstance = this;
        
        // If there is content in the element, then apply the out Fx and then the in Fx
        // otherwise just the in Fx
        var text = $(destination).get('text');
        if (text == "")
        {
            siteManagerInstance.transitionContentIn(content, destination)
        }
        else
        {
            //console.log('Applying Fx out/in');
            var fadeOut = new Fx.Tween(
                $(destination),
                {
                    property : 'opacity',
                    duration : Settings.FX_OUT_DURATION,
                    onComplete : function()
                    {
                        siteManagerInstance.transitionContentIn(content, destination)
                    }
                });
            
            fadeOut.start(1, 0);
        }

    },
    
    transitionContentIn : function(content, destination)
    {
        destination = $(destination);
        console.log('transitionContentIn');
        
        //console.log('Applying Fx in');
        // gets any js in the response and executes it... allows modules to define javascript
        var javascript = "";
        content = content.stripScripts(function(script){ javascript = script });
    
        // dispose of the children of this element before setting HTML
        var children = destination.getChildren();
        for (var index = 0; index < children.length; ++index)
        {
            var child = children[index];
            child.dispose();
            child = null;
        }
        
        destination.set('opacity', 0);
        destination.set('html', content);
        
        this.transitionIn(destination);
        this.registerFormElements();
        $exec(javascript);
    },
    
    transitionIn : function(element)
    {
        var fadeIn = new Fx.Tween($(element), { property : 'opacity', duration : Settings.FX_IN_DURATION });
        fadeIn.start(0, 1);
    },
    
    processMessage : function(responseText, responseXml)
    {
        var siteManagerInstance = this;
        
        //console.log(responseText);
        
        var responseObject = JSON.decode(responseText);
        
        if (responseObject.content)
        {
            responseObject.content.each(
                function(contentObject)
                {
                    siteManagerInstance.setContent(Base64.decode(contentObject.content), contentObject.destination);
                }
            );
        }
        else if (responseObject.project)
        {
            if (_project)
                _project = responseObject.project;
            
            if (responseObject.module && setView)
                setView( responseObject.module );
                
        }
        else if (responseObject.navigate)
        {
            window.location = responseObject.navigate;
        }
        else if (responseObject.script)
        {
            $exec(Base64.decode(responseObject.script));
        }
    },
    
    setElementError: function(field, element, responseObject)
    {
        var siteManagerInstance = this;
        
        if (element)
        {
            var errorMessages = "";
            var errors = responseObject.errors[field];
            
            errors.each(function(item, index){ errorMessages += item + "\n";});
            
            var errorMessageTitle = 'Error';
            
            if (errors.length > 1) errorMessageTitle = 'Errors'
            
            var elementType = element.get('type');
            
            // We don't want to do anything to radio buttons
            if (!elementType || elementType.toLowerCase() != 'radio')
            {
                var borderColor = element.getStyle("border-color");
                siteManagerInstance.defaultBackgroundStyle = borderColor;
                
                element.setStyle("border-color", Settings.ERROR_COLOR);
                
                // Make sure that the color is back to normal before highlighting
                if (element.getStyle("background-color").toLowerCase() == "#ffffff")
                    element.highlight(Settings.ERROR_COLOR);
                    
                element.set('rel', errorMessages);
                element.set('title', errorMessageTitle);
            }
            
            var label = $(document.body).getElement('label[for=id_' + field + ']');
            if (!label)
            {
                // Works for multiple choice fields like radio input
                label = $(document.body).getElement('label[for=id_' + field + '_0]');
                if (label)
                {
                    // Make sure that the color is back to normal before highlighting
                    var tempColor = label.getStyle("background-color").toLowerCase();
                    if (tempColor == "#ffffff" || tempColor == 'transparent')
                        label.highlight(Settings.ERROR_COLOR);
                }
            }
            
            if (label)
            {
                label.set('rel', errorMessages);
                label.set('title', errorMessageTitle);
            }
            
            $$([element, label]).each(
                function(element)
                {
                    element.removeEvent('mouseenter', element.retrieve('tip:enter') || $empty);
                    element.removeEvent('mouseleave', element.retrieve('tip:leave') || $empty);
                    element.removeEvent('mousemove', element.retrieve('tip:move') || $empty);
                    element.eliminate('tip:enter').eliminate('tip:leave').eliminate('tip:move');
                });
            
            var tip = new Tips([element, label], { className: 'error-tool' });
            
            if (window['errorHandler_' + field])
            {
                window['errorHandler_' + field](errors);
            }
        }
    },
    
    showErrors: function(responseObject)
    {
        var errorList = $('id_errorContainer');
        if (errorList)
        {
            var errorHtml = '';
            
            if (!errorList.attributes['static'])
            {
                errorHtml = '<div class="errorList"><h3><img src="/media/partner/images/icon_important.gif">&nbsp;An Error Occurred</h3><ul>';
                for (var field in responseObject.errors)
                {
                    var errors = responseObject.errors[field];
                    errors.each(function(item, index){ errorHtml += '<li>' + item + '</li>';});
                }
                errorHtml += '</ul></div>';
            
            }
            else
            {
                errorHtml = errorList.get('html');
                errorList.setStyle('opacity', 0);
                errorList.setStyle('display', '');
            }
            
            this.transitionContentIn(errorHtml, errorList);
        }
    },
    
    processFormSubmitResponse: function(form, event, responseText, responseXml)
    {
        var siteManagerInstance = this;
        var responseObject = JSON.decode(responseText);
        
        this.showNormal();
        
        if (responseObject)
        {
            // Remove tooltips for all form elements
            elements = form.getElements('input, select, textarea, label');
            elements.removeEvents('mouseenter');
            elements.each(function(item, index)
                {
                    if (siteManagerInstance.defaultBackgroundStyle)
                        item.setStyle("border-color", siteManagerInstance.defaultBackgroundStyle);
                });
            
            $$('div[class=error-tool]').dispose();
            
            // If we have a validation response and it has errors
            if (responseObject.valid != null && !responseObject.valid)
            {
                // Process errors on the form
                console.warn('The form was INVALID');
                this.showErrors(responseObject);
                for (var field in responseObject.errors)
                {
                    console.log("Processing errors for : ", field);
                    var element = $('id_' + field);
                    
                    if (!element)
                    {
                        // This will work for radio buttons...
                        element = $(document.body).getElement('input[name=' + field + ']');
                        
                        if (!element)
                        {
                            // Last thing to try is find a visible element using named convention
                            var elementArray = $(document.body).getElements('select[name^=' + field + '],input[name^=' + field + '_]');
                        
                            if (elementArray)
                            {
                                // Then select the first element to attach to
                                for (var counter = 0; counter < elementArray.length; counter++)
                                {
                                    var tempElement = elementArray[counter];
                                    if (!tempElement.getProperty('type') || tempElement.getProperty('type').toLowerCase() != 'hidden')
                                    {
                                        siteManagerInstance.setElementError(field, tempElement, responseObject);
                                    }
                                }
                            }
                        }
                    }
                    
                    if (element)
                    {
                        siteManagerInstance.setElementError(field, element, responseObject);
                    }
                }
                
                var found = false;
                // Set focus to the first error on the form
                for (var index = 0; !found && index < elements.length; ++index)
                {
                    var element = elements[index];
                    
                    for (var field in responseObject.errors)
                    {
                        if ("id_" + field == element.id)
                        {
                            try
                            {
                                element.focus();
                            }
                            finally
                            {
                                found = true;
                                break;
                            }
                        }
                    }
                }
            }
            else
            {
                this.processMessage(responseText);
            }
        }
    },
    
    onFormSubmit: function(form, event)
    {
        var siteManagerInstance = this;
        var actionUrl = null;
        if (form.attributes['action'])
        {
            actionUrl = form.attributes["action"].value;
        }
        var validationUrl = form.attributes['validation'].value;
        var showWait = form.attributes["showwait"] != null && form.attributes["showwait"].value == 'true';

        var formElements = form.getElements('input[type!=submit], select, textarea, button')
        var data = "";
        var button = null;
        
        // Get the origin button
        if (event.explicitOriginalTarget)
        {
            button = event.explicitOriginalTarget;
        }
        else if (event.relatedTarget)
        {
            button = event.relatedTarget;
        }
        else
        {
            button = document.activeElement;
        }
        
        button = $(button);
        
        if (button)
        {
            formElements.include(button);
            
            // Disable wait button if it's a back/cancel situation
            var buttonText = (button.get('value') ? button.get('value') : button.get('text')).toLowerCase();
            showWait &= !((buttonText == 'back') || (buttonText == 'cancel'));
        }
        
        formElements.each(
            function(item, index)
            {
                var addElement = true;
                
                if ((item.type == 'checkbox' || item.type == 'radio') && !item.checked)
                    addElement = false;
                    
                if (addElement)
                    data += item.name + "=" + encodeURIComponent(item.get('value') != null ? item.get('value') : item.get('text')) + "&";
            });
        
        request = new Request(
            {
                url         : actionUrl ? actionUrl : validationUrl,
                method      : 'POST',
                onRequest   : function(instance){ if (showWait) siteManagerInstance.showWait(); },
                onFailure   : function(instance){ alert('Response Code: ' + instance.status); },
                onException : function(headerName, value){ },
                onCancel    : function(){ },
                onSuccess   : function(responseText, responseXml)
                {
                    siteManagerInstance.processFormSubmitResponse(form, event, responseText, responseXml);
                }
            });                         
        
        request.send(data);
    },
    
    webForm_FireDefaultButton : function(event)
    {
        if (event.key == 'enter' && !(event.target && event.target.tagName.toLowerCase() == "textarea"))
        {
            var defaultButton = null;
            
            while(true)
            {
                // Find our default button on the form by the value
                defaultButton = $(event.target.form).getElement('input[value=next]');
                if (defaultButton) break;
                defaultButton = $(event.target.form).getElement('input[value=NEXT]');
                if (defaultButton) break;
                defaultButton = $(event.target.form).getElement('input[value=submit]');
                if (defaultButton) break;
                defaultButton = $(event.target.form).getElement('input[value=SUBMIT]');
                if (defaultButton) break;
                defaultButton = $(event.target.form).getElement('input[value=save]');
                if (defaultButton) break;
                defaultButton = $(event.target.form).getElement('input[value=SAVE]');
                if (defaultButton) break;
                defaultButton = $(event.target.form).getElement('input[value=login]');
                if (defaultButton) break;
                defaultButton = $(event.target.form).getElement('input[value=LOGIN]');
                
                break;
            }
            
            if (defaultButton && typeof defaultButton.click != "undefined")
            {
                defaultButton.click();
                event.stop();
                event.stopPropagation();
                return false;
            }
        }
        else (event.key == 'escape')
        {
            this.showNormal();
        }
        return true;
    },
    
    registerFormElements: function()
    {
        var siteManagerInstance = this;
        
        // TODO: This needs to cache each click handler and remove them for each submit button
        var inputClickEventHandler =
                function(event)
                {
                    try
                    {
                        document.activeElement = this;
                    }
                    catch (exception) { }
                };
        
        $$('input[type=submit]').each(
            function(element)
            {
                element.removeEvent('click', inputClickEventHandler);
                element.addEvent('click', inputClickEventHandler);
            });
        
        // Get all forms and add submit events for those that define validationurl
        var forms = $(document.body).getElements('form[validation!=]');
        
        if (!this._formSubmitEventHandler)
        {
            this._formSubmitEventHandler =
                function(event)
                {
                    event.stop();
                    event.stopPropagation();
                    event.preventDefault();
                    siteManagerInstance.onFormSubmit(this, event);
                };
        }
            
        if (!this._formKeyPressEventHandler)
        {
            this._formKeyPressEventHandler =
                function(event)
                {
                    siteManagerInstance.webForm_FireDefaultButton(event);
                };
        }
        
        if (forms)
        {
            for (var index = 0; index < forms.length; ++index)
            {
                var form = forms[index];
                form.removeEvent('keypress', this._formKeyPressEventHandler);
                form.addEvent('keypress', this._formKeyPressEventHandler);
        
                form.removeEvent('submit', this._formSubmitEventHandler);
                form.addEvent('submit', this._formSubmitEventHandler);
            }
        }        
    },
    
    start: function()
    {
        var siteManagerInstance = this;
        this.registerFormElements();
        
        if (window.blockManagerUrl)
        {
            // Startup screen, do a synchronous post for the initial content,
            // needs be done to get the dom setup
            var startRequest = new Request(
                {
                    url         : blockManagerUrl,
                    async       : true,
                    evalScripts : true,
                    method      : "GET",
                    onRequest   : function(instance){ },
                    onFailure   : function(instance){ alert('Response Code: ' + instance.status); },
                    onException : function(headerName, value){ },
                    onCancel    : function(){ },
                    onSuccess   : function(responseText, responseXml)
                    {
                        siteManagerInstance.processMessage(responseText, responseXml);
                    }
                }
            );
            
            startRequest.send();
        }
	}
});

var siteManager = new SiteManager();

window.addEvent('load', function (){ siteManager.start(); });
