/*
 * $Id: faba5.richeditor-1.0.js 2299 2011-08-17 09:17:53Z markus.tripp@fabasoft.com $
 * 
 * Copyright © Fabasoft R&D GmbH, A-4020 Linz, 1995-2011.
 * 
 * All rights reserved. All hardware and software names used are registered trade names and/or registered trademarks of  
 * the respective manufacturers.
 * 
 * The user of this computer program acknowledges that the above copyright notice, which constitutes the Universal 
 * Copyright Convention, will be attached at the position in the function of the computer program which the author has 
 * deemed to sufficiently express the reservation of copyright. It is prohibited for customers, users and/or third  
 * parties to remove, modify or move this copyright notice.
 * 
 * This computer program is protected by copyright law and international treaties. Unauthorized reproduction or 
 * redistribution of this program, or any portion of it, may result in severe civil and criminal penalties.
 * 
 * The use of this software requires a valid license agreement for this software. This license agreement specifies 
 * especially permitted use through the licensing model. A license agreement must already exist prior to installing the 
 * software as the installation process of this software does not include the conclusion of a license agreement.
 */

(function() {
    jQuery.widget("faba5.richeditor", {
        _create : function() {
            this._createInspector();
        },
        
        close : function() {
            this._inspector.dialog('close');
        },
        
        value : function() {
            return this.editorElement.editor('value');
        },
        
        _createInspector : function() {
            if (!this._initialized) {
                this._inspector = $('#finspector');
                
                this._initButtons();
                this._initLink();
                this._initImage();

                this._tabs = this._inspector.find('.ftabs');
                this._tabs.tabs();
                this._initTabSelect();

                this._inspector.dialog({
                    closeOnEscape: false,
                    autoOpen: false,
                    resizable: false,
                    width: 350,
                    minWidth: 350,
                    maxWidth: 1200,
                    open: function(event, ui) {
                        $(this).closest('.ui-dialog').find('.ui-dialog-titlebar-close').hide();
                    }
                });

                this._initialized = true;
            }
        },
        
        open : function(el) {
            var self = this;
            
            this.editorElement = el;
            this.editorElement.editor();
            
            this.editorElement.dblclick(function(event){
                self._onDblClick(event);
            });

            var left = this.editorElement.offset().left + this.editorElement.outerWidth() + 3;
            var top = this.editorElement.offset().top - $(document).scrollTop();
            
            this._inspector.dialog('option', 'position', [left, top]);
            this._inspector.dialog('open');
        },
        
        _initButtons : function() {
            this._initHeadings();
            this._initClear();
            
            this._initButton('finspectorBold', 'ui-icon-font-style-bold', 'bold', 'isBoldPossible');
            this._initButton('finspectorItalic', 'ui-icon-font-style-italic', 'italic', 'isItalicPossible');
            this._initButton('finspectorUnder', 'ui-icon-font-style-underline', 'underline', 'isUnderlinePossible');

            this._initButton('finspectorLeft', 'ui-icon-align-left', 'left', 'isLeftPossible');
            this._initButton('finspectorCenter', 'ui-icon-align-center', 'center', 'isCenterPossible');
            this._initButton('finspectorRight', 'ui-icon-align-right', 'right', 'isRightPossible');

            this._initButton('finspectorUL', 'ui-icon-list-unordered', 'unordered', 'isUnorderedPossible');
            this._initButton('finspectorOL', 'ui-icon-list-ordered', 'ordered', 'isOrderedPossible');
            this._initButton('finspectorIndent', 'ui-icon-arrowthickstop-1-e', 'indent', 'isIntendPossible');
            this._initButton('finspectorOutdent', 'ui-icon-arrowthickstop-1-w', 'outdent', 'isOutdentPossible');
        },
        
        _initButton : function(id, icon, action, check) {
            var self = this;
            
            $('#' + id).button({
                icons: {
                    primary: icon
                },
                text: false
            }).click(function() {
                if (self.editorElement.editor(check)) {
                    self.editorElement.editor(action);
                }
            });
        },
        
        _initHeadings : function() {
            var self = this;

            $('#finspectorHeadings').button({
                icons: {
                    secondary: 'ui-icon-triangle-1-s'
                }
            }).click(function() {
                if (!$('.foptionsList').is(':visible')) {
                    var list = $('<ul class="foptionsList"></ul>');
                    $.each(['1','2','3'], function(i, val) {
                        var link = $('<a href="#">Heading ' + val + '</a>').click(function() {
                            self.editorElement.editor('formatblock', 'H' + val);
                        });
                        
                        $('<li></li>').append(link).appendTo(list);
                    });
                    $(this).options(list, true);
                }
            });
        },
        
        _initClear : function() {
            var self = this;
            
            $('#finspectorClear').button({
                icons: {
                    primary: 'ui-icon-cancel'
                },
                text: false
            }).click(function() {
                var node = self.editorElement.editor('getRawSelection').anchorNode;
                if (node) {
                    var parent = $(node.parentNode);
                    
                    if (self._replaceInline(parent)) {
                        parent.replaceWith(parent.text());
                    } else if (self._replaceParagraph(parent)) {
                        parent.replaceWith('<p>' + parent.text() + '</p>');
                    } else if (self._replaceList(parent)) {
                        var list = parent.parent();
                        list.replaceWith('<p>' + list.text() + '</p>');
                    }
                }
            });
        },
        
        _initLink : function() {
            var self = this;
            
            $('#finspectorInsertLink').button().click(function() {
                if ($('#finspectorImageContainer').is(':empty')) {
                    if ($('#finspectorLink').val() == '') {
                        var linkTab = $('#finspectorTab-2');
                        linkTab.message(linkTab.data('error-link-fields'), {type: 'ferror'});
                    } else {
                        var anchor = self._createAnchor();
                        
                        self.editorElement.editor('restoreSelection');
                        self.editorElement.editor('overwrite', anchor.get(0));
                        
                        anchor.focus();
                        
                        self._cleanLink();
                        self._tabs.tabs('select', 0);
                    }
                } else {
                    self._applyImage();
                } 
            });
        },
        
        _createAnchor : function() {
            var linkURL = $('#finspectorLink');
            var linkTitle = $('#finspectorLinkTitle');
            var newWindow = $('#finspectorNewWindow');

            var anchor = $('<a/>').attr('href', linkURL.val()).text(linkURL.val());

            if (linkTitle.val() != '') {
                anchor.text(linkTitle.val());
            }

            if (newWindow.is(':checked')) {
                anchor.attr('target', '_blank');
            }
            
            return anchor;
        },
        
        _initTabSelect : function() {
            var self = this;
            
            this._tabs.bind('tabsselect', function(event, ui) {
                if (ui.index == 1) {
                    self._initLinkTabSelect(self);
                }
                
                return true;
            });
        },
        
        _initLinkTabSelect : function(self) {
            var linkTitle = $('#finspectorLinkTitle');
            var sel = self.editorElement.editor('getRawSelection');
            var node = sel.anchorNode;
            
            if (node) {
                var parent = $(node.parentNode);
                
                if (parent.is('a')) {
                    self.editorElement.editor('saveSelection', node.parentNode);
                    self._prefillLink(parent);
                }
            }
            
            if (linkTitle.val().length == 0) {
                var selectedText = sel;
                
                if (sel.text) {
                    selectedText = sel.text;
                }
                
                linkTitle.val(selectedText);
            }
        },

        _replaceInline : function(el) {
            return el.is('b') || el.is('i') || el.is('u') || 
                el.is('strong') || el.is('em') || el.is('a') || el.is('span[style]');
        },
        
        _replaceParagraph : function(el) {
            return el.is('h1') || el.is('h2') || el.is('h3');
        },
        
        _replaceList : function(el) {
            return el.is('li');
        },
        
        _prefillLink : function(el) {
            if (el) {
                var linkURL = $('#finspectorLink');
                var linkTitle = $('#finspectorLinkTitle');
                var newWindow = $('#finspectorNewWindow');
                
                linkURL.val(el.attr('href'));
                linkTitle.val(el.text());
                
                if (el.attr('target') == '_blank') {
                    newWindow.attr('checked', 'checked');
                } else {
                    newWindow.removeAttr('checked');
                }
            }
        },
        
        _cleanLink : function() {
            $('#finspectorLink').val('');
            $('#finspectorLinkTitle').val('');
            $('#finspectorNewWindow').removeAttr('checked');
        },
        
        _onDblClick : function(event) {
            var node = event.target;
            var tagname = node.tagName.toLowerCase();
    
            if (tagname == 'img') {
                this.editorElement.blur();
                this.editorElement.editor('saveSelection', node);
                
                var imageElement = $(node);
                var anchor;
                
                var imageUrl = imageElement.attr('src');
                var shadow = imageElement.css('box-shadow') != 'none';
                var parent = imageElement.parent();
                
                if (parent.is('a')) {
                    this.editorElement.editor('saveSelection', node.parentNode);
                    
                    anchor = parent.clone();
                    anchor.text(imageElement.attr('title'));
                }
                
                this._showImage(imageUrl, shadow, anchor);

                this._tabs.tabs('select', 2);
            } else if (tagname == 'a') {
                this.editorElement.blur();
                this.editorElement.editor('saveSelection', node);
                
                this._prefillLink($(node));
                this._tabs.tabs('select', 1);
            } 
        },
        
        _initImage : function() {
            var self = this;
            
            this._initImageUpload();
            this._initImageScale();
            this._initImageCrop();
            
            $('#finspectorShadow').button().click(function() {
                if ($(this).attr('checked')) {
                    $('#finspectorImageContainer img').css('box-shadow', '2px 2px 10px 2px rgba(0,0,0,0.5)');
                } else {
                    $('#finspectorImageContainer img').css('box-shadow', '');
                }
            });
            
            $('#finspectorImageApply').button().click(function() {
                self._applyImage();
            });
            
            $('#finspectorImageCancel').button().click(function() {
                self._inspector.dialog('option', 'width', 350);
                self._cleanImage();
                self._tabs.tabs('select', 0);
            });
            
            $('#finspectorImageRestore').button().click(function() {
                var url = $('#finspectorImageContainer img').attr('src');
                var path = $('html').data('path');
                
                $.ajax({
                    type: 'GET',
                    url: path + '/api/image/restore.json',
                    data: {
                        url: url
                    },
                    success: function(data) {
                        var shadow = $('#finspectorShadow').attr('checked') ? true : false;
                        
                        self._cleanImage();
                        self._showImage(url, shadow);
                    },
                    error: function(jqXHR, textStatus, errorThrown) {
                        console.log('error ' + textStatus + ' ' + errorThrown);
                    }
                });
            });
        },
        
        _applyImage : function() {
            var self = this;
            
            var image = $('#finspectorImageContainer img').clone();
            var width = image.css('width');
            var height = image.css('height');
            
            if (width != '0px' && height != '0px') {
                var url = image.attr('src');
                var w = width.substring(0, width.length - 2);
                var h = height.substring(0, height.length - 2);
                
                image.css('width', '');
                image.css('height', '');

                var path = $('html').data('path');

                $.ajax({
                    type: 'GET',
                    url: path + '/api/image/scale.json',
                    data: {
                        url: url,
                        w: w,
                        h: h
                    },
                    success: function(data) {
                        image.attr('src', self._appendTimestamp(url));
                        self._cleanApplyImage(image);
                    },
                    error: function(jqXHR, textStatus, errorThrown) {
                        console.log('error ' + textStatus + ' ' + errorThrown);
                        
                        $('#finspectorImageCrop').hide();
                        $('#finspectorImageEdit').show();
                    }
                });
            } else {
                this._cleanApplyImage(image);
            }
        },
        
        _cleanApplyImage : function(image) {
            var element = this._getImageElement(image);
            
            this.editorElement.editor('restoreSelection');
            this.editorElement.editor('overwrite', element.get(0));
            
            image.focus();

            this._inspector.dialog('option', 'width', 350);
            this._cleanImage();
            this._cleanLink();
            this._tabs.tabs('select', 0);
        },
        
        _getImageElement : function(image) {
            if ($('#finspectorLink').val() == '') {
                return image;
            }
            
            var anchor = this._createAnchor();
            image.attr('title', anchor.text());
            
            anchor.empty().append(image);
            
            return anchor;
        },
        
        _cleanImage : function() {
            $('#finspectorImageContainer').empty();
            $('#finspectorShadow').removeAttr('checked');
            $('#finspectorScale').slider('value', 100);
            
            $('#finspectorImageEdit').hide();
            $('#finspectorImageForm').show();
        },
        
        _initImageUpload : function() {
            var self = this;
            
            $('#finspectorImageUpload').button().click(function() {
                if ($('#finspectorImageFile').val()) {
                    $('#finspectorImageForm').ajaxSubmit({
                        dataType: 'json',
                        success: function(data) {
                            self._cleanLink();
                            self._showImage(data.url);
                        }
                    });
                } else {
                    $('#finspectorTab-3').message('Please select file first', {type: 'ferror'});
                }
                
                return false;
            });
        },
        
        _showImage : function(url, shadow, anchor) {
            var self = this;
            
            if (anchor) {
                this._prefillLink(anchor);
            }
            
            $('#finspectorImageForm').hide();
            $('#finspectorImageEdit').show();
            $('#finspectorShadow').removeAttr('checked');
            
            var imageContainer = $('#finspectorImageContainer'); 
            imageContainer.empty();
            imageContainer.data('url', url);
            
            var imageUrl = this._appendTimestamp(url);
            
            var image = $('<img/>').attr('src', imageUrl);
            if (shadow) {
                $('#finspectorShadow').attr('checked', 'checked');
                image.css('box-shadow', '2px 2px 10px 2px rgba(0,0,0,0.5)');
            }
            
            $('#finspectorShadow').button().click(function() {
                if ($(this).attr('checked')) {
                    $('#finspectorImageContainer img').css('box-shadow', '2px 2px 10px 2px rgba(0,0,0,0.5)');
                } else {
                    $('#finspectorImageContainer img').css('box-shadow', '');
                }
            });
            
            image.load(function() {
                $('#finspectorImageContainer').data('width', this.width);
                $('#finspectorImageContainer').data('height', this.height);
                
                var value = '(' + this.width + 'x' + this.height + 'px - 100%)';
                $('#finspectorScaleSize').html(value);
                
                self._inspector.dialog('option', 'width', this.width + 60);
            }).appendTo(imageContainer);
            
            $('#finspectorImageFile').val('');
        },
        
        _appendTimestamp : function(url) {
            var cleanUrl = this._removeTimestamp(url);
            return cleanUrl + '?t=' + new Date().getTime();
        },
        
        _removeTimestamp : function(url) {
            var index = url.indexOf('?');
            if (index == -1) {
                return url;
            }
            
            return url.substring(0, index);
        },
        
        _initImageScale : function() {
            var self = this;
            
            $('#finspectorScale').slider({
                value: 100,
                min: 5,
                max: 200,
                step: 5,
                slide: function(event, ui) {
                    var width = parseInt($('#finspectorImageContainer').data('width') * ui.value / 100);
                    var height = parseInt($('#finspectorImageContainer').data('height') * ui.value / 100);
                    
                    var value = '(' + width + 'x' + height + 'px - ' + ui.value + '%)';

                    $('#finspectorScaleSize').html(value);
                    
                    $('#finspectorImageContainer img').css('width', width);
                    $('#finspectorImageContainer img').css('height', height);
                    
                    self._inspector.dialog('option', 'width', width + 60);
                }
            });
        },
        
        _initImageCrop : function() {
            var self = this;
            var c;
            
            $('#finspectorCrop').button().click(function() {
                $('#finspectorImageEdit').hide();
                
                var image = $('#finspectorImageContainer img').clone();
                image.removeAttr('width').removeAttr('height').removeAttr('style');
                
                $('#finspectorImageCropContainer').empty().append(image);
                
                image.Jcrop({
                    onChange: function(c) { self.c = c; },
                    onSelect: function(c) { self.c = c; },
                    onRelease: function(c) { self.c = c; }
                });
                
                $('#finspectorImageCrop').show();
            });
            
            $('#finspectorImageActionCrop').button().click(function() {
                var url = $('#finspectorImageCropContainer img').attr('src');
                var path = $('html').data('path');
                
                $.ajax({
                    type: 'GET',
                    url: path + '/api/image/crop.json',
                    data: {
                        url: url,
                        xa: self.c.x,
                        xb: self.c.x2,
                        ya: self.c.y,
                        yb: self.c.y2
                    },
                    success: function(data) {
                        var shadow = $('#finspectorShadow').attr('checked') ? true : false;
                        
                        self._cleanImage();
                        self._showImage(url, shadow);
                        
                        $('#finspectorImageCrop').hide();
                        $('#finspectorImageEdit').show();
                    },
                    error: function(jqXHR, textStatus, errorThrown) {
                        console.log('error ' + textStatus + ' ' + errorThrown);
                        
                        $('#finspectorImageCrop').hide();
                        $('#finspectorImageEdit').show();
                    }
                });
            });
            
            $('#finspectorImageActionCancel').button().click(function() {
                $('#finspectorImageCrop').hide();
                $('#finspectorImageEdit').show();
            });
        }
    });
})();

