Clientcide.setAssetLocation(resource_path + '/clientcide/Assets')

var ME_PROXY_EMULATOR_MODE  = false;
var ME_PROXY_EMULATOR_DELAY = 500;

var ME_JSON_PROXY_EMULATOR_DATA = new Hash({
    'augustskolan' : new Hash({
        'getMenu' : {
            'title'   : 'Ställ en fråga till Augustskolan',
            'actions' : [
                {
                    'title'         : 'Ställ fråga',
                    'url'           : 'add_question',
                    'tooltip'       : 'Ställ en ny fråga',
                    'updateStatus'  : false,
                    'updateMessage' : false
                }
            ]
        },
        'getStatus' : {
            'title'        : 'Fråga till',
            'recipient'    : 'Augustskolan',
            'recipientUrl' : 'dummy_url'
        }
    }),
    
    'oppet_hus_fraga' : new Hash({
        'getMenu' : {
            'title'   : 'Läs diskussion med Augustskolan',
            'actions' : [
                {
                    'title'         : 'Läs diskussion',
                    'url'           : 'oppet_hus_fraga_las',
                    'tooltip'       : 'Läs inlägg i denna diskussionstråd',
                    'updateStatus'  : false,
                    'updateMessage' : false
                },
                {
                    'title'         : 'Markera oläst',
                    'url'           : 'oppet_hus_fraga_mark_unread',
                    'tooltip'       : 'Markera denna diskussionstråd som ej läst',
                    'updateStatus'  : true,
                    'updateMessage' : false
                },
                {
                    'title'         : 'Markera obesvarad',
                    'url'           : 'oppet_hus_fraga_mark_unanswered',
                    'tooltip'       : 'Markera denna diskussionstråd som ej besvarad',
                    'updateStatus'  : true,
                    'updateMessage' : false
                }
            ]
        },
        'getStatus' : {
            'title'        : 'Fråga till',
            'recipient'    : 'Augustskolan',
            'recipientUrl' : 'dummy_url',
            
            'status' : [
                {
                    'title'   : 'Läst',
                    'tooltip' : 'Denna tråd är läst'
                },
                {
                    'title'   : 'Obesvarad',
                    'tooltip' : 'Denna tråd är ej besvarad'
                }
            ]
        }
    })
});

var ME_AJAX_PROXY_EMULATOR_URL_CONTENTS = new Hash({});

var MEAJAXProxyEmulator = new Class({
    Implements : [Events],
    
    initialize : function () {
        self.url_contents = new Hash();
    },
    
    getURL : function (caller, success_callback, url) {
        (function () {
            if (ME_AJAX_PROXY_EMULATOR_URL_CONTENTS.has(url)) {
                success_callback.bind(caller, self.url_contents.get(url))();
            }
            else {
                success_callback.bind(caller, 'Inneh&aring;ll saknas.')();
            }
            
            this.fireEvent('complete');
        }).delay(ME_PROXY_EMULATOR_DELAY, this);
    },
    
    postData : function (caller, success_callback, url, data) {
        (function () {
            if (ME_AJAX_PROXY_EMULATOR_URL_CONTENTS.has(url)) {
                success_callback.bind(caller, self.url_contents.get(url))();
            }
            else {
                success_callback.bind(caller, 'Inneh&aring;ll saknas.')();
            }
            
            this.fireEvent('complete');
        }).delay(ME_PROXY_EMULATOR_DELAY, this);
    }
});

var MEAJAXProxy = new Class({
    Implements : [Events],
    
    getURL : function (caller, success_callback, url) {
        new Request({
            'url'    : url,
            'method' : 'get',
            
            'onSuccess' : function (response_text, response_xml) {
                success_callback.bind(caller, response_text)();
                
                this.fireEvent('complete');
            }.bind(this)
        }).send();
    },
    
    postData : function (caller, success_callback, url, data) {
        new Request({
            'url'         : url,
            'method'      : 'post',
            'data'        : data,
            'evalScripts' : true,
            
            'onSuccess' : function (response_text, response_xml) {
                success_callback.bind(caller, response_text)();
                
                this.fireEvent('complete');
            }.bind(this)
        }).send();
    }
});

var MEStepAJAXProxyEmulator = new Class({
    Implements: [Events],
    
    initialize: function (step_dict) {
        if (step_dict) {
            $extend(this, step_dict);
        }
    },
    
    setData: function (step_dict) {
        $extend(this, step_dict);
    },
    
    getContent: function (caller, callback) {
        (function () {
            if (this.url === 'dummy_url_step_1') {
                callback.bind(caller, 'Step 1 content')();
            }
            else if (this.url === 'dummy_url_step_2') {
                callback.bind(caller, 'Step 2 content')();
            }
            else if (this.url === 'dummy_url_step_3') {
                callback.bind(caller, 'Step 3 content')();
            }
            else if (this.url === 'dummy_url_publish') {
                callback.bind(caller, 'Publish this item')();
            }
            else {
                callback.bind(caller, 'No content')();
            }
            
            this.fireEvent('complete');
        }).delay(ME_PROXY_EMULATOR_DELAY, this);
    }
});


var MEStepAJAXProxy = new Class({
    Implements: [Events],
    
    initialize: function (step_dict) {
        if (step_dict) {
            $extend(this, step_dict);
        }
    },
    
    setData: function (step_dict) {
        $extend(this, step_dict);
    },
    
    getContent: function (caller, callback) {
        new Request.HTML({
            'url' : this.url,
            'onSuccess' : function (tree, elements, html, scripts) {
                callback.bind(caller, html)();
                
                this.fireEvent('complete');
            }.bind(this)
        }).send();
    }
});


var MEPageAJAXProxyEmulator = new Class({
    Implements: [Events],
    
    initialize: function (page_dict) {
        if (page_dict) {
            $extend(this, page_dict);
        }
    },
    
    setData: function (page_dict) {
        $extend(this, page_dict);
    },
    
    getSteps: function (caller, callback) {
        (function () {
            if (this.stepsUrl === 'dummy_url_edit_steps') {
                callback.bind(caller, {
                    'pages' : [
                        {
                            'title'   : 'Step 1',
                            'url'     : 'dummy_url_edit_step_1',
                            'status'  : 'completed',
                            'requiresAllPreviousCompleted' : false,
                            'tooltip' : 'This is step 1'
                        },
                        {
                            'title'   : 'Step 2',
                            'url'     : 'dummy_url_edit_step_2',
                            'status'  : 'completed',
                            'requiresAllPreviousCompleted' : false,
                            'tooltip' : 'This is step 2'
                        },
                        {
                            'title'   : 'Step 3',
                            'url'     : 'dummy_url_edit_step_3',
                            'status'  : 'empty',
                            'requiresAllPreviousCompleted' : false,
                            'tooltip' : 'This is step 3'
                        },
                        {
                            'title'   : 'Publish',
                            'url'     : 'dummy_url_edit_publish',
                            'status'  : 'empty',
                            'requiresAllPreviousCompleted' : true,
                            'tooltip' : 'Publish this item!'
                        }
                    ]
                })();
            }
            else {
                callback.bind(caller, { 'pages' : [] })();
            }
            
            this.fireEvent('complete');
        }).delay(ME_PROXY_EMULATOR_DELAY, this);
    },
    
    getContent: function (caller, callback) {
        (function () {
            if (this.url === 'dummy_url_info') {
                callback.bind(caller, 'General information')();
            }
            else if (this.url === 'dummy_url_edit') {
                callback.bind(caller, 'Edit this object')();
            }
            else if (this.url === 'dummy_url_manage') {
                callback.bind(caller, 'Manage object status')();
            }
            else {
                callback.bind(caller, 'No content')();
            }
            
            this.fireEvent('complete');
        }).delay(ME_PROXY_EMULATOR_DELAY, this);
    }
});


var MEPageAJAXProxy = new Class({
    Implements: [Events],
    
    initialize: function (page_dict) {
        if (page_dict) {
            $extend(this, page_dict);
        }
    },
    
    setData: function (page_dict) {
        $extend(this, page_dict);
    },
    
    getSteps: function (caller, callback) {
        new Request.JSON({
            'url' : this.stepsUrl,
            
            'onSuccess' : function (response_data) {
                callback.bind(caller, response_data)();
                
                this.fireEvent('complete');
            }.bind(this)
        }).send();
    },
    
    getContent: function (caller, callback) {
        new Request.HTML({
            'url' : this.url,
            'onSuccess' : function (tree, elements, html, scripts) {
                callback.bind(caller, html)();
                
                this.fireEvent('complete');
            }.bind(this)
        }).send();
    }
});


var MEObjectAJAXProxyEmulator = new Class({
    Implements: [Events],
    
    initialize: function (url) {
        this.url = url;
    },
    
    getPages: function (caller, callback) {
        (function () {
            callback.bind(caller, {
                'title' : 'Example Object',
                'pages' : [
                    {
                        'title'    : 'Information',
                        'url'      : 'dummy_url_info',
                        'tooltip'  : 'Miscellaneous information about this object.'
                    },
                    {
                        'title'    : 'Edit Content',
                        'url'      : 'dummy_url_edit_step_1',
                        'tooltip'  : 'Edit this object.',
                        'stepsUrl' : 'dummy_url_edit_steps'
                    },
                    {
                        'title'    : 'Manage Status',
                        'url'      : 'dummy_url_manage',
                        'tooltip'  : 'Access management functions.'
                    }
                ]
            })();
            
            this.fireEvent('complete');
        }).delay(ME_PROXY_EMULATOR_DELAY, this);
    },
    
    postData : function (caller, success_callback, url, data) {
        (function () {
            success_callback.bind(caller, 'Inneh&aring;ll saknas.')();
            
            this.fireEvent('complete');
        }).delay(1500, this);
    }
});


var MEObjectAJAXProxy = new Class({
    Implements: [Events],
    
    initialize: function (url) {
        if (url === undefined || url === null) {
            throw new Error('Error: base url must be specified.');
        }
        
        this.url = url;
    },
    
    getPages: function (caller, callback) {
        new Request.JSON({
            'url' : this.url + '/getPages',
            
            'onSuccess' : function (response_data) {
                callback.bind(caller, response_data)();
                
                this.fireEvent('complete');
            }.bind(this)
        }).send();
    },
    
    postData : function (caller, success_callback, url, data) {
        new Request.HTML({
            'url'    : url,
            'method' : 'post',
            'data'   : data,
            
            'onSuccess' : function (tree, elements, html, scripts) {
                success_callback.bind(caller, html)();
                
                this.fireEvent('complete');
            }.bind(this)
        }).send();
    }
});


var MsgEObjectAJAXProxyEmulator = new Class({
    Implements: [Events],
    
    initialize: function (url) {
        this.url = url;
    },
    
    getMenu: function (caller, callback) {
        (function () {
            callback.bind(caller, ME_JSON_PROXY_EMULATOR_DATA[this.url]['getMenu'])();
            
            this.fireEvent('complete');
        }).delay(ME_PROXY_EMULATOR_DELAY, this);
    },
    
    getStatus: function (caller, callback) {
        (function () {
            callback.bind(caller, ME_JSON_PROXY_EMULATOR_DATA[this.url]['getStatus'])();
            
            this.fireEvent('complete');
        }).delay(ME_PROXY_EMULATOR_DELAY, this);
    }
});

var MsgEObjectAJAXProxy = new Class({
    Implements: [Events],
    
    initialize: function (url) {
        if (url === undefined || url === null) {
            throw new Error('Error: base url must be specified.');
        }
        
        this.url = url;
    },
    
    getMenu: function (caller, callback, apropos) {
        var data;
        
        data = {};
        
        if (apropos) {
            data.apropos = apropos;
        }
        
        new Request.JSON({
            'url'  : this.url + '/getMenu',
            'data' : data,
            
            'onSuccess' : function (response_data) {
                callback.bind(caller, response_data)();
                
                this.fireEvent('complete');
            }.bind(this)
        }).send();
    },
    
    getStatus: function (caller, callback) {
        new Request.JSON({
            'url' : this.url + '/getStatus',
            
            'onSuccess' : function (response_data) {
                callback.bind(caller, response_data)();
                
                this.fireEvent('complete');
            }.bind(this)
        }).send();
    }
});


var ModalEditorViewController = new Class({
    Implements: [Class.Occlude],
    property: 'modal_editor_controller',
    
    initialize: function (element, modal_editor, object_path) {
        this.element = element;
        
        if (this.occlude()) return this.occluded;
        
        this.modal_editor = modal_editor;
        
        this.tooltip_manager = new Tips.Pointy(null, {
            'fixed' : true,
            
            'pointyTipOptions' : {
                'pointyOptions' : {
                    'theme' : 'light'
                }
            }
        });
        
        this.setObjectPath(object_path);
        
        this.updating = false;
        
        return this;
    },
    
    setObjectPath: function (object_path) {
        this.object_path = object_path;
        
        this.ajax_proxy = this.getAJAXProxy();
        
        this.object_ajax_proxy = this.getObjectProxy();
        
        this.object_ajax_proxy.getPages(this, function (json_data) {
            this.element.empty();
            
            this.element.grab(new Element('h2', {
                'id'   : 'modaleditor_title',
                'text' : json_data.title
            }));
            
            menu_element = new Element('div', {
                'id' : 'modaleditor_page_menu'
            });
            
            this.element.grab(menu_element);
            
            this.menu_view = new MEMenuView(menu_element, this, json_data.pages);
            
            content_element = new Element('div', {
                'id' : 'modaleditor_content'
            });
            
            this.content_view = new MEContentView(content_element, this);
            
            this.element.grab(content_element);
            
            this.content_view.loadPage(json_data.pages[0]);
        });
    },
    
    menuClicked: function (itemNr, page_dict) {
        if (this.updating) return;
        
        if (this.menu_view) {
            this.menu_view.gotoMenuItem(itemNr);
        }
        
        if (this.content_view) {
            this.content_view.loadPage(page_dict);
        }
    },
    
    stepClicked: function (stepNr) {
        if (this.updating) return;
        
        if (this.content_view && this.content_view.step_menu_view) {
            this.content_view.step_menu_view.gotoStep(stepNr);
            
            //this.content_view.loadStep(step_dict);
            this.content_view.loadCurrentStep();
        }
    },
    
    nextStep: function () {
        if (this.updating) return;
        
        if (this.content_view && this.content_view.step_menu_view) {
            this.content_view.step_menu_view.nextStep();
            
            this.content_view.loadCurrentStep();
        }
    },
    
    postData : function (url, data) {
        this.ajax_proxy.postData(this, function (response_html) {
            if (this.content_view) {
                if (this.content_view.step_menu_view && this.content_view.current_page_dict && this.content_view.current_page_dict.stepsUrl) {
                    this.content_view.step_menu_view.update();
                }
                
                this.content_view.setContent(response_html);
            }
        }, url, data);
    },
    
    attachTip: function (elements) {
        this.tooltip_manager.attach(elements);
    },
    
    detachTip: function (elements) {
        this.tooltip_manager.detach(elements);
    },
    
    exit: function () {
        this.modal_editor.exit();
    },
    
    getPageProxy: function (page_dict) {
        if (ME_PROXY_EMULATOR_MODE) {
            return new MEPageAJAXProxyEmulator(page_dict);
        }
        else {
            return new MEPageAJAXProxy(page_dict);
        }
    },
    
    getStepProxy: function (step_dict) {
        if (ME_PROXY_EMULATOR_MODE) {
            return new MEStepAJAXProxyEmulator(step_dict);
        }
        else {
            return new MEStepAJAXProxy(step_dict);
        }
    },
    
    getObjectProxy: function () {
        if (ME_PROXY_EMULATOR_MODE) {
            return new MEObjectAJAXProxyEmulator(this.object_path);
        }
        else {
            return new MEObjectAJAXProxy(this.object_path);
        }
    },
    
    getAJAXProxy: function () {
        if (ME_PROXY_EMULATOR_MODE) {
            return new MEAJAXProxyEmulator();
        }
        else {
            return new MEAJAXProxy();
        }
    },
    
    windowResized: function (event) {
        if (this.content_view) {
            this.content_view.windowResized(event);
        }
    }
});

var MessageEditorViewController = new Class({
    Extends: ModalEditorViewController,
    property: 'message_editor_controller',
    
    initialize: function (element, modal_editor, object_path) {
        this.apropos = modal_editor.apropos;
        
        this.parent(element, modal_editor, object_path);
        
        return this;
    },
    
    setObjectPath: function (object_path) {
        var worker_group, menu_json_data, status_json_data;
        
        this.object_path = object_path;
        
        this.ajax_proxy = this.getAJAXProxy();
        
        this.menu_object_proxy = this.getObjectProxy();
        
        this.status_object_proxy = this.getObjectProxy();
        
        worker_group = new Group(this.menu_object_proxy, this.status_object_proxy);
        
        worker_group.addEvent('complete', function () {
            this.element.empty();
            
            this.element.grab(new Element('h2', {
                'id'   : 'modaleditor_title',
                'text' : menu_json_data.title
            }));
            
            menu_element = new Element('div', {
                'id' : 'modaleditor_page_menu'
            });
            
            this.element.grab(menu_element);
            
            this.menu_view = new MsgEMenuView(menu_element, this, menu_json_data.actions);
            
            content_element = new Element('div', {
                'id' : 'modaleditor_content'
            });
            
            this.content_view = new MsgEContentView(content_element, this);
            
            this.content_view.step_menu_view.construct(status_json_data);
            
            this.element.grab(content_element);
            
            this.content_view.loadPage(menu_json_data.actions[0]);
        }.bind(this));
        
        this.menu_object_proxy.getMenu(this, function (json_data) {
            menu_json_data = json_data;
        }.bind(this), this.apropos);
        
        this.status_object_proxy.getStatus(this, function (json_data) {
            status_json_data = json_data;
        }.bind(this));
    },
    
    getObjectProxy: function () {
        if (ME_PROXY_EMULATOR_MODE) {
            return new MsgEObjectAJAXProxyEmulator(this.object_path);
        }
        else {
            return new MsgEObjectAJAXProxy(this.object_path);
        }
    },
    
    menuClicked: function (itemNr, page_dict) {
        if (this.menu_view) {
            this.menu_view.gotoMenuItem(itemNr);
        }
        
        if (this.content_view) {
            this.content_view.loadPage(page_dict);
        }
    }
});

var MEMenuView = new Class({
    Implements: [Class.Occlude],
    property: 'element',
    
    initialize: function (element, view_controller, pages) {
        var ul_items, li_item;
        
        this.element = element;
        
        if (this.occlude()) return this.occluded;
        
        this.view_controller = view_controller;
        this.pages = pages;
        
        this.element.empty();
        
        this.marker = new Element('div', {
            'id'   : 'modaleditor_page_menu_marker',
            'html' : '&nbsp;'
        });
        
        this.element.grab(this.marker);
        
        ul_items = new Element('ul');
        
        pages.each(function (page, index) {
            if (page.spacer) {
                li_item = new Element('li', {
                    'class' : 'me_menu_spacer'
                });
                
                ul_items.grab(li_item);
            }
            else {
                li_item = new Element('li', {
                    'title' : page.title,
                    'rel'   : page.tooltip
                });
                
                li_item.grab(new Element('a', {
                    'href' : '#',
                    'text' : page.title
                }));
                
                ul_items.grab(li_item);
                
                li_item.getChildren()[0].addEvent('click', function (event) {
                    this.view_controller.menuClicked(index, page);
                    
                    event.stop();
                }.bind(this));
                
                this.view_controller.attachTip(li_item);
            }
        }.bind(this));
        
        li_item = new Element('li', {
            'class' : 'exit',
            'title' : 'St&auml;ng',
            'rel'   : 'St&auml;ng editorn och &aring;terg&aring;.'
        });
        
        li_item.grab(new Element('a', {
            'href' : '#',
            'html' : 'St&auml;ng&nbsp;&nbsp;&nbsp;[esc]'
        }));
        
        ul_items.grab(li_item);
        
        this.view_controller.attachTip(li_item);
        
        li_item.getChildren()[0].addEvent('click', function (event) {
            this.view_controller.exit();
            
            event.stop();
        }.bind(this));
        
        this.element.grab(ul_items);
        
        this.element.setStyles({
            'height' : ul_items.getCoordinates().height + 8 +'px'
        });
        
        this.marker_slide_fx = new Fx.Tween(this.marker, {
            'duration'   : 100,
            'property'   : 'margin-top',
            'transition' : 'sine:in:out'
        });
        
        return this;
    },
    
    gotoMenuItem: function (itemNr) {
        this.marker_slide_fx.start(9 + (28 * itemNr));
    }
});

var MsgEMenuView = new Class({
    Extends: MEMenuView,
    
    initialize: function (element, view_controller, actions) {
        var ul_items, li_item;
        
        this.element = element;
        
        if (this.occlude()) return this.occluded;
        
        this.view_controller = view_controller;
        this.actions = actions;
        
        this.element.empty();
        
        this.marker = new Element('div', {
            'id'   : 'modaleditor_page_menu_marker',
            'html' : '&nbsp;'
        });
        
        this.element.grab(this.marker);
        
        ul_items = new Element('ul');
        
        actions.each(function (action, index) {
            li_item = new Element('li', {
                'title' : action.title,
                'rel'   : action.tooltip
            });
            
            li_item.grab(new Element('a', {
                'href' : '#',
                'text' : action.title
            }));
            
            ul_items.grab(li_item);
            
            li_item.getChildren()[0].addEvent('click', function (event) {
                this.view_controller.menuClicked(index, action);
                
                event.stop();
            }.bind(this));
            
            this.view_controller.attachTip(li_item);
        }.bind(this));
        
        li_item = new Element('li', {
            'class' : 'exit',
            'title' : 'St&auml;ng',
            'rel'   : 'St&auml;ng editorn och &aring;terg&aring;.'
        });
        
        li_item.grab(new Element('a', {
            'href' : '#',
            'html' : 'St&auml;ng&nbsp;&nbsp;&nbsp;[esc]'
        }));
        
        ul_items.grab(li_item);
        
        this.view_controller.attachTip(li_item);
        
        li_item.getChildren()[0].addEvent('click', function (event) {
            this.view_controller.exit();
            
            event.stop();
        }.bind(this));
        
        this.element.grab(ul_items);
        
        this.element.setStyles({
            'height' : ul_items.getCoordinates().height + 8 +'px'
        });
        
        return this;
    },
    
    gotoMenuItem: function (itemNr) { }
});

var MEStepMenuView = new Class({
    Implements: [Class.Occlude],
    property: 'element',
    
    initialize: function (element, content_view, view_controller) {
        this.element = element;
        
        if (this.occlude()) return this.occluded;
        
        this.content_view    = content_view;
        this.view_controller = view_controller;
        
        this.marker = new Element('div', {
            'id'   : 'modaleditor_step_menu_marker',
            'html' : '&nbsp;'
        });
        
        this.marker_slide_fx = new Fx.Morph(this.marker, {
            'duration'   : 100,
            'transition' : 'sine:in:out'
        });
        
        this.clear();
        
        this.current_step = 0;
        
        return this;
    },
    
    setStep: function (stepNr) {
        var step, step_element_coords;
        
        step = this.steps.pages[stepNr];
        
        step_element_coords = step.element.getCoordinates(this.marker.getParent());
        
        if (this.marker_slide_fx && step.element) {
            this.marker_slide_fx.set({
                'left'  : step_element_coords.left  - 14  + 'px',
                'width' : step_element_coords.width + 28 + 'px'
            });
        }
        
        this.current_step = stepNr;
    },
    
    gotoStep: function (stepNr) {
        var step, step_element_coords;
        
        this.current_step = stepNr;
        
        this.update(function () {
            step = this.steps.pages[stepNr];
            
            step_element_coords = step.element.getCoordinates(this.marker.getParent());
            
            if (this.marker_slide_fx && step.element) {
                this.marker_slide_fx.start({
                    'left'  : step_element_coords.left  - 14  + 'px',
                    'width' : step_element_coords.width + 28 + 'px'
                });
            }
        }.bind(this));
    },
    
    nextStep: function () {
        if (this.steps.pages.length > this.current_step + 1) {
            this.gotoStep(this.current_step + 1);
        }
    },
    
    clear: function () {
        this.steps = null;
        
        this.view_controller.detachTip(this.element.getElements('ul > li'));
        
        this.element.empty();
        
        this.element.setStyles({
            'visibility' : 'hidden'
        });
        
    },
    
    populate: function (steps) {
        var ul_steps, li_step, a_step, all_previous_completed;
        
        this.steps = steps;
        
        this.element.empty();
        
        this.element.setStyles({
            'visibility' : 'visible'
        });
        
        this.element.grab(this.marker);
        
        ul_steps = new Element('ul');
        
        ul_steps.grab(new Element('li', {
            'class' : 'title',
            'text'  : 'Steg:'
        }));
        
        all_previous_completed = true;
        
        steps.pages.each(function (step, index) {
            li_step = new Element('li', {
                'title' : step.title,
                'rel'   : step.tooltip
            });
            
            step.element = li_step;
            
            if (step.status === 'completed') {
                li_step.set('class', 'completed');
                
                li_step.grab(new Element('img', {
                    'class' : 'marker',
                    'src'   : resource_path + '/images/trans.gif'
                }));
            }
            
            if (step.requiresAllPreviousCompleted === false || all_previous_completed) {
                a_step = new Element('a', {
                    'href' : '#',
                    'text' : step.title
                });
                
                a_step.addEvent('click', function (event) {
                    event.stop();
                    
                    this.view_controller.stepClicked(index);
                }.bind(this));
                
                li_step.grab(a_step);
            }
            else {
                li_step.set('text', step.title);
            }
            
            ul_steps.grab(li_step);
            
            this.view_controller.attachTip(li_step);
            
            if (index < (steps.pages.length - 1)) {
                ul_steps.grab(new Element('li', {
                    'html' : '&gt;'
                }));
            }
            
            if (step.status != 'completed') {
                all_previous_completed = false;
            }
        }.bind(this));
        
        this.element.grab(ul_steps);
        
        this.setStep(this.current_step);
    },
    
    getCurrentStepDict: function () {
        return this.steps.pages[this.current_step];
    },
    
    update: function (complete_callback) {
        var page_steps_ajax_proxy;
        
        page_steps_ajax_proxy = this.view_controller.getPageProxy(this.content_view.current_page_dict);
        
        if (complete_callback) {
            page_steps_ajax_proxy.addEvent('complete', complete_callback);
        }
        
        page_steps_ajax_proxy.getSteps(this, function (steps) {
            this.populate(steps);
        }.bind(this));
    },
    
    windowResized: function (event) { }
});

var MsgEStatusBarView = new Class({
    Extends: MEStepMenuView,
    
    construct: function (status_json_data) {
        var ul_status_bar, li_element, a_element;
        
        this.element.empty();
        
        this.element.setStyles({
            'visibility' : 'visible'
        });
        
        ul_status_bar = new Element('ul');
        
        ul_status_bar.grab(new Element('li', {
            'text' : status_json_data.title
        }));
        
        li_element = new Element('li', {
            'class' : 'title'
        });
        
        li_element.grab(new Element('a', {
            'href' : status_json_data.recipientUrl,
            'text' : status_json_data.recipient
        }));
        
        ul_status_bar.grab(li_element);
        
        if (status_json_data.status) {
            status_json_data.status.each(function (status_item, index) {
                li_step = new Element('li', {
                    'class' : 'status',
                    'rel'   : status_item.tooltip
                });
                
                li_step.appendText('[');
                
                if (status_item.iconUrl) {
                    li_step.grab(new Element('img', {
                        'src' : status_item.iconUrl
                    }));
                }
                
                if (status_item.title) {
                    li_step.set('title', status_item.title);
                    li_step.appendText(status_item.title);
                }
                
                li_step.appendText(']');
                
                ul_status_bar.grab(li_step);
                
                this.view_controller.attachTip(li_step);
            }.bind(this));
        }
        
        this.element.grab(ul_status_bar);
    },
    
    update: function (complete_callback) {
        var object_ajax_proxy;
        
        object_ajax_proxy = this.view_controller.getObjectProxy();
        
        if (complete_callback) {
            object_ajax_proxy.addEvent('complete', complete_callback);
        }
        
        object_ajax_proxy.getStatus(this, function (json_data) {
            this.construct(json_data);
        }.bind(this));
    }
});

var MEContentView = new Class({
    Implements: [Class.Occlude],
    property: 'element',
    
    initialize: function (element, view_controller) {
        var step_menu_element;
        
        this.element = element;
        
        if (this.occlude()) return this.occluded;
        
        this.view_controller = view_controller;
        
        this.element.empty();
        
        step_menu_element = new Element('div', {
            'id' : 'modaleditor_step_menu'
        });
        
        this.element.grab(step_menu_element);
        
        this.step_menu_view = new MEStepMenuView(step_menu_element, this, this.view_controller);
        
        this.content_container = new Element('div', {
            'class' : 'content'
        });
        
        this.element.grab(this.content_container);
        
        this.content_view_fade_fx = new Fx.Tween(this.element, {
            'property'   : 'opacity',
            'duration'   : 'short',
            'transition' : 'linear',
            'link'       : 'chain'
        });
        
        this.content_view_fade_fx.set(0);
        
        this.initially_hidden = true;
        
        this.updating = false;
        
        this.content_container_fade_fx = new Fx.Tween(this.content_container, {
            'property'   : 'opacity',
            'duration'   : 'short',
            'transition' : 'linear'
        });
        
        return this;
    },
    
    setContent: function (content_html) {
        var form_data, form_action_url;
        
        this.content_container.set('html', content_html);
        
        this.content_container.getElements('form').each(function (form_element) {
            form_element.getElements('input').each(function (input_element) {
                input_element.addEvent('keydown', function (event) {
                    if (event.key === 'enter') {
                        event.stop();
                    }
                }.bind(this));
            }.bind(this));
            
            if (form_element.get('target') != 'json') {
                form_element.addEvent('submit', function (event) {
                    event.stop();
                }.bind(this));
                
                form_element.getElements('input[type="submit"]').each(function (button_element) {
                    button_element.addEvent('click', function (event) {
                        event.stop();
                        
                        form_data = form_element.toQueryString().parseQueryString();
                        
                        form_data[button_element.get('id')] = button_element.get('value');
                        
                        form_action_url = new URI(form_element.get('action'));
                        
                        this.view_controller.postData(form_action_url.toString(), form_data);
                    }.bind(this));
                }.bind(this));   
            }
        }.bind(this));
        
        this.content_container.getElements('a').each(function (a_element) {
            if (a_element.get('target') !== 'json') {
                a_element.addEvent('click', function (event) {
                    var ajax_proxy;
                    
                    event.stop();
                    
                    ajax_proxy = this.view_controller.getAJAXProxy();
                    
                    ajax_proxy.getURL(this, function (response_text) {
                        this.setContent(response_text);
                    }, a_element.get('href'));
                }.bind(this));
            }
        }.bind(this));
        
        activate_elements(this.content_container);
        
        //(function () {
            if ($defined(window.init_tinymce)) {
                init_tinymce();
            }
        //}).delay(1000);
        
        //this.content_container.getElements('textarea.mceEditor').each(function (editor_element) {
        //    //var editor;
        //    //
        //    //editor = new tinymce.Editor(editor_element.get('id'));
        //    //tinyMCE.add(editor);
        //    //editor.render(1);
        //    
        //    //(function () {
        //        tinyMCE.execCommand('mceAddControl', false, editor_element.get('id'));
        //    //}).delay(1000);
        //}.bind(this));
    },
    
    loadPage: function (page_dict) {
        var content_html, steps, workers, worker_group, content_ajax_proxy;
        
        this.current_page_dict = page_dict;
        
        content_ajax_proxy = this.view_controller.getAJAXProxy();
        
        workers = [content_ajax_proxy];
        
        if (!this.initially_hidden) {
            workers.push(this.content_view_fade_fx);
        }
        
        worker_group = new Group(workers);
        
        worker_group.addEvent('complete', function () {
            var step_menu_element, step_menu_height;
            
            this.setContent(content_html);
            
            if (steps) {
                this.step_menu_view.populate(steps);
                
                step_menu_element = this.step_menu_view.element;
                step_menu_height = step_menu_element.getSize().y + parseInt(step_menu_element.getStyle('margin-top'), 10) + parseInt(step_menu_element.getStyle('margin-bottom'), 10);
                
                this.content_container.setStyles({
                    'top'    : '48px',
                    'height' : (this.content_container.getParent().getSize().y - step_menu_height) - 3 + 'px'
                });
            }
            else {
                this.step_menu_view.clear();
                
                this.content_container.setStyles({
                    'top'    : '0px',
                    'height' : this.content_container.getParent().getSize().y - 3 + 'px'
                });
            }
            
            this.content_view_fade_fx.start(1);
            
            this.initially_hidden = false;
            this.view_controller.updating = false;
        }.bind(this));
        
        if (!this.initially_hidden) {
            this.content_view_fade_fx.start(0);
        }
        
        if (page_dict.stepsUrl) {
            current_step = this.step_menu_view && this.step_menu_view.current_step || 0;
            
            page_steps_ajax_proxy = this.view_controller.getPageProxy(page_dict);
            
            page_steps_ajax_proxy.getSteps(this, function (_steps) {
                steps = _steps;
                
                content_ajax_proxy.getURL(this, function (response_text) {
                    content_html = response_text;
                }, steps.pages[current_step].url);
            });
        }
        else {
            content_ajax_proxy.getURL(this, function (response_text) {
                content_html = response_text;
            }, page_dict.url);
        }
        
        this.view_controller.updating = true;
    },
    
    loadStep: function (step_dict) {
        var step_ajax_proxy, content_update_group, content_html, workers;
        
        step_ajax_proxy = this.view_controller.getStepProxy(step_dict);
        
        workers = [step_ajax_proxy, this.content_container_fade_fx];
        
        content_update_group = new Group(workers);
        
        content_update_group.addEvent('complete', function () {
            this.setContent(content_html);
            
            this.view_controller.updating = false;
            
            this.content_container_fade_fx.start(1);
        }.bind(this));
        
        this.content_container_fade_fx.start(0);
        
        this.view_controller.updating = true;
        
        step_ajax_proxy.getContent(this, function (_content_html) {
            content_html = _content_html;
        });
    },
    
    loadCurrentStep: function () {
        if (this.step_menu_view) {
            this.loadStep(this.step_menu_view.getCurrentStepDict());
        }
    },
    
    windowResized: function (event) {
        var step_menu_element, step_menu_height, parent_height;
        
        step_menu_element = this.step_menu_view.element;
        
        
        if (this.content_container.getParent().getSize().y !== 0) {
            if (step_menu_element.getStyle('visibility') != 'hidden') {
                step_menu_height = step_menu_element.getSize().y + parseInt(step_menu_element.getStyle('margin-top'), 10) + parseInt(step_menu_element.getStyle('margin-bottom'), 10);
            }
            else {
                step_menu_height = 0;
            }
            
            this.content_container.setStyle('height', (this.content_container.getParent().getSize().y - step_menu_height) - 3 + 'px');
        }
        
        if (this.step_menu_view) {
            this.step_menu_view.windowResized(event);
        }
    }
});

var MsgEContentView = new Class({
    Extends: MEContentView,
    
    initialize: function (element, view_controller) {
        var step_menu_element;
        
        this.element = element;
        
        if (this.occlude()) return this.occluded;
        
        this.view_controller = view_controller;
        
        this.element.empty();
        
        step_menu_element = new Element('div', {
            'id' : 'modaleditor_step_menu'
        });
        
        this.element.grab(step_menu_element);
        
        this.step_menu_view = new MsgEStatusBarView(step_menu_element, this, this.view_controller);
        
        this.content_container = new Element('div', {
            'class' : 'content'
        });
        
        this.element.grab(this.content_container);
        
        this.content_view_fade_fx = new Fx.Tween(this.element, {
            'property'   : 'opacity',
            'duration'   : 'short',
            'transition' : 'linear',
            'link'       : 'chain'
        });
        
        this.content_view_fade_fx.set(0);
        
        this.initially_hidden = true;
        
        this.content_container_fade_fx = new Fx.Tween(this.content_container, {
            'property'   : 'opacity',
            'duration'   : 'short',
            'transition' : 'linear'
        });
        
        return this;
    },

    loadPage: function (page_dict) {
        var content_html, status_json_data, steps, workers, worker_group, content_ajax_proxy;
        
        content_ajax_proxy = this.view_controller.getAJAXProxy();
        status_object_proxy = this.view_controller.getObjectProxy();
        
        content_ajax_proxy.addEvent('complete', function () {
            status_object_proxy.getStatus(this, function (json_data) {
                status_json_data = json_data;
            }.bind(this));
        }.bind(this));
        
        workers = [status_object_proxy];
        
        if (!this.initially_hidden) {
            workers.push(this.content_view_fade_fx);
        }
        
        worker_group = new Group(workers);
        
        worker_group.addEvent('complete', function () {
            var step_menu_element, step_menu_height;
            
            this.setContent(content_html);
            this.step_menu_view.construct(status_json_data);
            
            step_menu_element = this.step_menu_view.element;
            step_menu_height = step_menu_element.getSize().y + parseInt(step_menu_element.getStyle('margin-top'), 10) + parseInt(step_menu_element.getStyle('margin-bottom'), 10);
            
            this.content_container.setStyles({
                'top'    : '48px',
                'height' : this.content_container.getParent().getSize().y - step_menu_height - 2 + 'px'
            });
            
            this.content_view_fade_fx.start(1);
            
            this.initially_hidden = false;
        }.bind(this));
        
        if (!this.initially_hidden) {
            this.content_view_fade_fx.start(0);
        }
        
        content_ajax_proxy.getURL(this, function (response_text) {
            content_html = response_text;
        }, page_dict.url);
    }
});

var ModalEditor = new Class({
    Implements: [Class.Occlude, Events],
    property: 'modal_editor',
    
    initialize: function (object_path, controller_class) {
        var modal_editor_div, menu_element, content_element;
        
        this.element = $(document.body);
        
        if (this.occlude()) {
            this.occluded.setObjectPath(object_path);
            
            this.occluded.mask.show();
            
            document.body.addEvent('keydown', this.occluded._keydown);
            window.addEvent('keydown', this.occluded._keydown);
            
            $('modal').setStyles({
                'position' : 'fixed',
                'top'      : 0,
                'left'     : 0,
                'width'    : '100%',
                'height'   : '100%'
            });
            
            $$('html')[0].setStyle('overflow', 'hidden');
            
            return this.occluded;
        }
        
        this._keydown = function (event) {
            if (event.key === 'esc') {
                event.stop();
                
                this.exit();
            }
        }.bind(this);
        
        document.body.addEvent('keydown', this._keydown);
        window.addEvent('keydown', this._keydown);
        
        this.object_path = object_path;
        controller_class = controller_class || ModalEditorViewController;
        
        if ($('modal')) {
            this.mask = $('modal');
        }
        else {
            this.mask = new Mask(null, {
                'hideOnClick' : false,
                'id'          : 'modal'
            });
        }
        
        this.mask.show();
        
        $('modal').setStyles({
            'position' : 'fixed',
            'top'      : 0,
            'left'     : 0,
            'width'    : '100%',
            'height'   : '100%'
        });
        
        $$('html')[0].setStyle('overflow', 'hidden');
        
        window.addEvent('resize', this.windowResized.bindWithEvent(this));
        
        modal_editor_div = $('modal_content');
        
        if (!modal_editor_div) {
            modal_editor_div = new Element('div', {
                'id' : 'modal_content'
            });
            
            $('modal').grab(modal_editor_div);
        }
        
        this.view_controller = new controller_class(modal_editor_div, this, this.object_path);
        
        return this;
    },
    
    setObjectPath: function (object_path) {
        this.object_path = object_path;
        
        if (this.view_controller) {
            this.view_controller.setObjectPath(object_path);
        }
    },
    
    windowResized: function (event) {
        var window_size;
        
        window_size = window.getSize();
        
        $('modal').setStyles({
            'width'  : window_size.x + 'px',
            'height' : window_size.y + 'px'
        });
        
        if (this.view_controller) {
            this.view_controller.windowResized(event);
        }
    },
    
    nextStep: function () {
        this.view_controller.nextStep();
    },
    
    exit: function () {
        this.mask.hide();
        
        document.body.removeEvent('keydown', this._keydown);
        window.removeEvent('keydown', this._keydown);
        
       
        $$('html')[0].setStyle('overflow', null);
        
        // Hack: make sure scroll bars are only displayed if needed
        window.scrollBy(1, 1);
        window.scrollBy(-1, -1);
        
        this.fireEvent('close');
        
        this.removeEvents('close');
    }
});

var MessageEditor = new Class({
    Extends: ModalEditor,
    property: 'message_editor',
    
    initialize: function (object_path, apropos, controller_class) {
        controller_class = controller_class || MessageEditorViewController;
        
        this.apropos = apropos
        
        return this.parent(object_path, controller_class);
    }
    
});
