/*
A class for managing the editor.
*/

Editor = function() {
    
    /**
     * An instance of the editable settings.
     * @type EDITABLE.Settings
     */
    this.settings = new EDITABLE.Settings();
    
    /**
     * A map of editable collections that have local scope.
     * @type Object
     */
    this.local_collection_map = new Object();
    
    /**
     * A map of editable collections that have global scope.
     * @type Object
     */
    this.global_collection_map = new Object();

    /**
     * A timer for auto-saving. 
     * @type Timer
     * @private
     */
    this._timer = null;  
    
    /**
     * A function called each time the interface needs to reflect a change in
     * the editor. 
     * @type Function
     */
    this.on_change = function(ev) {};  
}

Editor.prototype.link_disable = function(ev) {
    return false;
};

Editor.prototype.start_edit = function() {
    // Disable link events
    $('a').bind('click', null, this.link_disable);
    
    // Build collections from editable 
    this.local_collection_map = new Object();
    var local_div_list = $('div.editable-local');
    for (var i=0; i<local_div_list.length; i++) {
        this.local_collection_map[$(local_div_list[i]).attr('id')] = new EDITABLE.Collection.from_node(local_div_list[i]);
        var collection = this.local_collection_map[$(local_div_list[i]).attr('id')];
        collection.bind('node_click', this, this.on_change);
        collection.bind('node_keyup', this, this.on_change);
        collection.bind('remove_node', this, Editor.prototype.on_remove_node);
        collection.bind('resize_node', this, Editor.prototype.on_resize_node);
        collection.commit();
    }
    this.global_collection_map = new Object();
    var global_div_list = $('div.editable-global');
    for (var i=0; i<global_div_list.length; i++) {
        this.global_collection_map[$(global_div_list[i]).attr('id')] = new EDITABLE.Collection.from_node(global_div_list[i]);
        var collection = this.global_collection_map[$(global_div_list[i]).attr('id')];
        collection.bind('node_click', this, this.on_change);
        collection.bind('remove_node', this, Editor.prototype.on_remove_node);
        collection.bind('resize_node', this, Editor.prototype.on_resize_node);
        collection.commit();    
    }
    
    // Set-up auto-saving
    if (this._timer) {
        this._timer.stopTime();
    }
    var _this = this;
    this._timer = $(this.node).everyTime(30*1000, function() {_this.save();});
    
    // Update the editors interface
    this.on_change();
}

Editor.prototype.finish_edit = function() {
    // Enable link events
    $('a').unbind('click', this.link_disable);
   
    // Re-render the collections
    for (collection_name in this.local_collection_map) {
        $('#'+collection_name).html(this.local_collection_map[collection_name].to_html());
    }
    for (collection_name in this.global_collection_map) {
        $('#'+collection_name).html(this.global_collection_map[collection_name].to_html());
    }
    if (this._timer) {
        this._timer.stopTime();
    }
}

Editor.prototype.save = function(callback) {
    var collection_map = new Object();
    var modified = false;
    for (collection_name in this.local_collection_map) {
        if (this.local_collection_map[collection_name].is_modified()) {
            collection_map[collection_name] = this.local_collection_map[collection_name].to_html();
            this.local_collection_map[collection_name].commit();
            modified = true;
        }
    } 
    for (collection_name in this.global_collection_map) {
        if (this.global_collection_map[collection_name].is_modified()) {
            collection_map[collection_name] = this.global_collection_map[collection_name].to_html();
            this.global_collection_map[collection_name].commit();
            modified = true;
        }
    }
    if (modified) {
        if (!callback) {
            callback = function(){app.notify('Auto-saved');}
        }
        $.post('/edit/update-page-content?record_id='+page.id, collection_map, callback, 'json');
    } else {
        if (callback) {
            callback();
        }
    }
}

Editor.prototype.on_remove_node = function(ev) {
    var node = ev.node;
    if (node && node.is_a('image')) {
        var image_src = node.src();
        var image_instance_id = image_src.match(/(\d+)-((w|h)\d+)+\.(gif|jpg|png)$/i)[1];
        $.post('/edit/delete-image-instance?record_id='+image_instance_id, {}, function(data) {
            ev.data.save();
        }, 'json');
    }
}

Editor.prototype.on_resize_node = function(ev) {
    var node = ev.node;
    if (node && node.is_a('image')) {
        var image_src = node.src();
        var image_instance_id = image_src.match(/(\d+)-((w|h)\d+)+\.(gif|jpg|png)$/i)[1];
        $.post('/edit/resize-image-instance', 
            {'record_id': image_instance_id, 'width': node.size()[0]}, 
            function(data) {
                // Reload the image
                node.src(data.data.complete_url);
                // Reset @@ max size
                ev.data.save();
            }, 'json');
    }
}

Editor.prototype.get_collection = function() {
    return this.settings.get_selected_collection();
}

Editor.prototype.get_node = function() {
    var collection = this.get_collection();
    if (collection) {
        var node = collection.get_selected_node();
        node.selection = SELECT.get(node.node)[0];
        return node;
    }
}

Editor.prototype.text_bold = function() {
    var node = this.get_node();
    if (node && node.is_a('text')) {
        if (node.get_selection() && !node.get_selection().is_collapsed()) {
            var soup = node.get_soup();
            var selection = node.get_selection().as_array();
            var strong_tag = new IXMO.Tag('strong');
            if (soup.has_tag(strong_tag, true, selection)==1) {
                soup.remove_tag(strong_tag, selection);
            } else {
                soup.apply_tag(strong_tag, selection);
            }
            node.render();
            node.select();
        }
    }
}

Editor.prototype.text_italic = function() {
    var node = this.get_node();
    if (node && node.is_a('text')) {
        if (node.get_selection() && !node.get_selection().is_collapsed()) {
            var soup = node.get_soup();
            var selection = node.get_selection().as_array();
            var em_tag = new IXMO.Tag('em');
            if (soup.has_tag(em_tag, true, selection)==1) {
                soup.remove_tag(em_tag, selection);
            } else {
                soup.apply_tag(em_tag, selection);
            }
            node.render();
            node.select();
        }
    }
}

Editor.prototype.text_align = function(align) {
    var node = this.get_node();
    if (node && node.is_a('text')) {
        node.align(align);
        node.select();
    }
}

Editor.prototype.request_link = function(node, selection, href) {
    href = href || '';
    _this = this;
    app.modal(true);
    var view = new UI.View(app.modal_panel, 
            null, 
            {title: "Insert link", 
            icon: RESOURCES.ICONS.PAGE_EDIT.LINK, 
            can_close: true});
    view.size([EDIT_VIEW.DEFAULT_VIEW_WIDTH, 'auto']);
    view.show(false);
    
    // Support for closing the view
    view.bind('close', null, function() {
        $('#insert-link-field').unautocomplete();
        app.modal(false);
        view.destroy();
        if (node && node.is_a('text')) {
            node.render();
            node.set_selection(selection[0], selection[1]);
        }
    });        

    var _form = new FORM.Form(null, null, null, 
        [new FORM.Fieldset('Link', 
            [new FORM.TextField('href', 'Link', '', 
                [new FORM.RequiredValidator(), 
                    new FORM.StringLenValidator({'min_length': 1, 'max_length': 255})], 
                'insert-link-field', {'class_name': 'form-medium'}),
            new FORM.SubmitField('submit','Insert','Insert')]
            )],
        'inser-link-form');
    _form.populate({'href': href});

    view.content = function(content_node) {
        _form.render(content_node);
        $('#insert-link-field').unautocomplete();
        $('#insert-link-field').autocomplete('/edit/linkable-autocomplete');
        $('#insert-link-field').result(function(ev, item) {
            $('#insert-link-field').val(item[1])
            return false;
            });
        _form.pre_callback = function(form, changed, valid, args) {
            if (changed || !valid) {
                if (valid) {
                    href = _form.get_field('href').get_value();
                    // Check href for email links
                    email_test = new FORM.EmailValidator();
                    if (email_test.validate(null, href).success) {
                        href = 'mailto:' + href;
                    }
                    _this._insert_link(href,
                        node, 
                        selection);
                    app.modal(false);
                    view.destroy();
                    if(node && node.is_a('text')) node.set_selection(selection[0], selection[1]);
                } else {
                    view.refresh_content();
                }
            }
            return false;
        };
        
        // @@ Select the first field
    };
    view.show();
    view.refresh();
}

Editor.prototype._insert_link = function(href, node, selection) {
    href = href.replace(/^\s+/g,'').replace(/\s+$/g,'');
    if (node && node.is_a('text')) {
        var soup = node.get_soup();
        var link_tag = new IXMO.Tag('a');
        soup.remove_all_tags(selection, 'a');
        if (href) {
            link_tag.set_attribute('href', href);
            soup.apply_tag(link_tag, selection);
        } 
        node.render();
    } else if (node && node.is_a('image')) {
        node.href(href);
    }
}

Editor.prototype.insert_link = function() {
    var node = this.get_node();
    if (node && node.is_a('text')) {
        var selection = node.get_selection();
        if (node.get_selection() && !node.get_selection().is_collapsed()) {
            var soup = node.get_soup();
            var link_tag = new IXMO.Tag('a');
            href = '';
            if(soup.has_tag(link_tag, true, selection.as_array()) > -1) {
                var prev_link_tag = soup.get_tag_list(selection.as_array(), 'a')[0];
                href = prev_link_tag.get_attribute('href');
            }        
            this.request_link(node, selection.as_array(), href);
        }    
    } else if (node && node.is_a('image')) {
        this.request_link(node, null, node.href());
    }
}

Editor.prototype.remove_link = function() {
    var node = this.get_node();
    if (node && node.is_a('text')) {
        if (node.get_selection() && !node.get_selection().is_collapsed()) {
            var soup = node.get_soup();
            var selection = node.get_selection().as_array(); 
            soup.remove_all_tags(selection, 'a');
            node.render();
            node.select();
        }
    } else if (node && node.is_a('image')) {
        node.href('');
    }
}

Editor.prototype.format = function(format_value) {
    var node = this.get_node();
    if (node && node.is_a('text')) {
        node.style('');
        node.element_type(format_value);
        node.select();
    }
}

Editor.prototype.style = function(style_value) {
    var node = this.get_node();
    if (node) {
        if (style_value.applicable_to == node.element_type() || style_value.applicable_to.indexOf(node.element_type()) >= 0) {
            node.style('');
            node.style(style_value.class_name);
        }
    }
}

Editor.prototype.clear_style = function() {
    var node = this.get_node();
    if (node) {
        node.style('');
        node.select();
    }
}

Editor.prototype.insert_image = function(paging) {
    var collection = this.get_collection();
    var node = this.get_node();
    if (node) {
        app.busy(true,true);
        $.getScript('/media/edit/js/apps/images.js',function() { 
            insert_from_images(paging, collection, node);
        });
    }
}

Editor.prototype.request_movie = function(collection, node) {
    _this = this;
    app.modal(true);
    var view = new UI.View(app.modal_panel, 
            null, 
            {title: "Insert movie", 
            icon: RESOURCES.ICONS.PAGE_EDIT.INSERT_MOVIE, 
            can_close: true});
    view.size([EDIT_VIEW.DEFAULT_VIEW_WIDTH, 'auto']);
    view.show(false);
    
    // Support for closing the view
    view.bind('close', null, function() {
        app.modal(false);
        view.destroy();
    });        

    var _form = new FORM.Form(null, null, null, 
        [new FORM.Fieldset('Movie', 
            [new FORM.TextField('url', 'Movie url', '', 
                [new FORM.RequiredValidator(), 
                    new FORM.StringLenValidator({'min_length': 1, 'max_length': 80})], 
                'insert-movie-url'),
            new FORM.TextField('alt', 'Title', '', 
                [new FORM.RequiredValidator(), 
                    new FORM.StringLenValidator({'min_length': 1, 'max_length': 80})], 
                'insert-movie-alt'),
            new FORM.SubmitField('submit','Insert','Insert')]
            ),],
        'inser-movie-form');

    view.content = function(content_node) {
        _form.render(content_node);
        _form.pre_callback = function(form, changed, valid, args) {
            if (changed || !valid) {
                if (valid) {
                    url = _form.get_field('url').get_value();
                    alt = _form.get_field('alt').get_value();
                    /* Query the movie */
                    var movie_provider = MOVIE.get_provider(url);
                    if (movie_provider && movie_provider.get_link_url()) {
                        _this._insert_movie(collection, node, url, alt);
                    } else {
                        alert('@@ Error this');
                        return false;
                    }
                    app.modal(false);
                    view.destroy();
                    node.set_selection(selection[0], selection[1]);
                } else {
                    view.refresh_content();
                }
            }
            return false;
        };
    };
    view.show();
    view.refresh();
}
 
Editor.prototype._insert_movie = function(collection, node, url, alt) {
    collection.add_movie(url, 
        [330, 190], 
        alt,
        {'max_width': 640},
        node);
}
           
Editor.prototype.insert_movie = function(paging) {
    var collection = this.get_collection();
    var node = this.get_node();
    if (node) {
        this.request_movie(collection, node);
    }
}

Editor.prototype.remove_shape = function(paging) {
    var collection = this.get_collection();
    var node = this.get_node();
    if (node && (node.is_a('image') || node.is_a('movie'))) {
        collection.remove_node(node);
    }
}

Editor.prototype.align_shape = function(align) {
    var node = this.get_node();
    if (node && (node.is_a('image') || node.is_a('movie'))) {
        node.align(node.get_final_type() + '-' + align);
        node.select();
    }
}
