/*
 * jQuery BB-code plugin 1.0
 *
 * Copyright (c) 2010 PFZ
 */
;(function($) {
    $.fn.PFZEditor = function( userOptions ) {
        var availableCodes = {
            bold: { code: '[b]', display: 'B', title: 'Dikgedrukt' },
            underline: { code: '[u]', display: 'U', title: 'Onderstreept' },
            italic: { code: '[i]', display: 'I', title: 'Schuingedrukt' },

            url: { code: '[url]', display: 'Url', title: 'Url' },
            topic: { code: '[topic]', display: 'Topic', title: 'Topic' },
            post: { code: '[post]', display: 'Post', title: 'Post' },
            wiki: { code: '[wiki]', display: 'Wiki', title: 'Wikiartikel' },
            rtfm: { code: '[rtfm]', display: 'RTFM', title: 'Read The Fucking Manual' },
            //lmgtfy: { code: '[lmgtfy]', display: 'LMGTFY', title: 'Let Me Google That For You' },

            img: { code: '[img]', display: 'Plaatje', title: 'Plaatje' },

            section: { code: '[section]', display: 'Kop 1', title: 'Kop 1' },
            subsection: { code: '[subsection]', display: 'Kop 2', title: 'Kop 2' },
            subsubsection: { code: '[subsubsection]', display: 'Kop 3', title: 'Kop 3' },

            code: { code: '[code]', display: 'Code', title: 'Code' },
            html: { code: '[html]', display: '(x)HTML', title: '(x)HTML-code' },
            php: { code: '[php]', display: 'PHP', title: 'PHP-code' },
            js: { code: '[js]', display: 'Javascript', title: 'Javascriptcode' },
            //javascript: { code: '[javascript]', display: 'Javascript', title: 'Javascriptcode' },
            css: { code: '[css]', display: 'CSS', title: 'CSS-code'  },
            sql: { code: '[sql]', display: 'SQL', title: 'SQL-code' },
            xml: { code: '[xml]', display: 'XML', title: 'XML-code' },

            quote: { code: '[quote]', display: 'Quote', title: 'Quote' },

            list: { code: '[list]', display: 'Lijst', title: 'Lijst' },
            ul: { code: '[ul]', display: 'Ongeordende lijst', title: 'Ongeordende lijst' },
            ol: { code: '[ol]', display: 'Genummerde lijst', title: 'Genummerde lijst' },
            li: { code: '[li]', display: 'Lijstitem', title: 'Lijstitem' },

            dl: { code: '[dl]', display: 'Definitielijst', title: 'Definitielijst' },
            dt: { code: '[dt]', display: 'Definitieterm', title: 'Definitieterm' },
            dd: { code: '[dd]', display: 'Definitiedata', title: 'Definitiedata' },

            ignore: { code: '[ignore]', display: 'Negeren', title: 'Negeren' },

            hr: { code: '[hr]', display: 'Horizontale lijn', title: 'Horizontale lijn' },
            notoc: { code: '[notoc]', display: 'Geen inhoudsopgave', title: 'Geen inhoudsopgave' }

        };

        var fontButtons = [ 'bold', 'underline', 'italic' ];
        var linkButtons = [ 'topic', 'post', 'wiki', 'url', 'rtfm', 'lmgtfy' ];
        var codeButtons = [ 'code', 'css', 'html', 'js', 'javascript', 'php', 'sql', 'xml' ];
        var sectionButtons = [ 'section', 'subsection', 'subsubsection' ];
        var listButtons = [ 'list', 'ul', 'ol', 'li' ];
        var definitionButtons = [ 'dl', 'dt', 'dd' ];
        var htmlButtons = [ 'hr', 'img' ];
        var specialButtons = [ 'ignore', 'notoc' ];
        var quoteButton = [ 'quote' ];

        var allButtons = [  fontButtons.concat( sectionButtons, linkButtons ),
                            quoteButton.concat( codeButtons ),
                            listButtons.concat( definitionButtons, htmlButtons, specialButtons ) ];

        var defaults = {
            autoresize: true,
            mode: 'forum'
        };
        /* {} kan weg??? */
        var options = $.extend( {}, defaults, userOptions );

        debug( this, defaults, userOptions, options );

        this.each( function( index, textareaNode ) {
            if ( $( this ).hasClass( 'script-editor' ) ) {
                var buttonRows = [ quoteButton.concat( linkButtons ), codeButtons, listButtons ];
            }
            else if ( $(this).hasClass( 'wiki-editor' ) ) {
                var buttonRows = allButtons;
            }
            /*
            else if ( $( this ).hasClass( 'forum-editor' ) ) {
                var buttonRows = [ quoteButton.concat( linkButtons ), codeButtons ];
            }
            */
            else {
                var buttonRows = [ quoteButton.concat( linkButtons ), codeButtons ];
            }

            for ( var property in buttonRows ) {
                if ( buttonRows.hasOwnProperty( property ) ) {
                    for ( var rowProperty in buttonRows[ property ] ) {
                        if ( buttonRows[ property ].hasOwnProperty( rowProperty ) ) {
                            var currentButton = buttonRows[ property ][ rowProperty ];
                            if ( !availableCodes[ currentButton ] ) {
                                buttonRows[ property ].splice( rowProperty, 1 );
                            }
                        }
                    }
                }
            }

            var siblingNode = textareaNode.nextSibling;
            var editorWidth = $( textareaNode ).outerWidth();

            var wrapperNode = $( document.createElement( 'div' ) );
            wrapperNode.width( editorWidth );
            //wrapperNode.css( 'width', editorWidth + 'px' );
            wrapperNode.addClass( 'pfz-editor' );
            for ( var property in buttonRows ) {
                var buttonRowNode = $( document.createElement( 'div' ) );
                buttonRowNode.addClass( 'pfz-editor-button-row' );
                wrapperNode.append( buttonRowNode );

                var buttonRow = buttonRows[ property ];
                for ( var buttonRowProperty in buttonRow ) {
                    var currentButton = buttonRow[ buttonRowProperty ];

                    var buttonNode = $( document.createElement( 'button' ) );
                    //buttonNode.attr( 'type', 'button' ); // <---- IE7 problem!!!
                    buttonNode.attr( 'title', availableCodes[ currentButton ].title );
                    buttonNode.append( document.createTextNode( availableCodes[ currentButton ].display ) );
                    buttonRowNode.append( buttonNode );

                    var openingTag = availableCodes[ currentButton ].code;
                    var closingTag = openingTag.substring( 0, 1 ) + '/' + openingTag.substring( 1 );

                    buttonNode.bind( 'click', { prefix: openingTag, postfix: closingTag }, function( event ) {
                        var prefix = event.data.prefix;
                        var postfix = event.data.postfix;
                        var targetElement = textareaNode;

                        if ( document.selection ) {
                            // make IE find selected text outside the textarea
                            targetElement.blur();
                            var selectedText = document.selection.createRange().text;
                        }
                        else {
                            var selectedText = window.getSelection().toString();
                        }

                        // there can also be text selected!
                        if ( targetElement.setSelectionRange ) { // W3C/Mozilla
                            var cursorStartPosition = targetElement.selectionStart;
                            var cursorEndPosition = targetElement.selectionEnd;
                            //alert( cursorStartPosition + ' t/m ' + cursorEndPosition );
                            if ( !selectedText.length ) {
                                // there is no text outside the textarea selected
                                selectedText = targetElement.value.substring( cursorStartPosition, cursorEndPosition );
                            }
                            newValue = prefix + selectedText + postfix;
                            var targetValue = targetElement.value;
                            //alert( targetValue.substring( 0, cursorStartPosition ) + newValue + targetValue.substring( cursorStartPosition ) );
                            targetElement.value = targetValue.substring( 0, cursorStartPosition ) + newValue + targetValue.substring( cursorStartPosition + selectedText.length );
                            targetElement.focus();
                            var cursorPosition = cursorStartPosition + prefix.length + selectedText.length;
                            targetElement.setSelectionRange( cursorPosition, cursorPosition );
                        }
                        else {
                            if ( document.selection && document.selection.createRange ) { // IE
                                // make IE use the textarea
                                targetElement.focus();
                                var range = document.selection.createRange();
                                if ( !selectedText.length ) {
                                    selectedText = range.text;
                                }
                                range.text = prefix + selectedText + postfix;
                                range.moveEnd( 'character', -postfix.length );
                                range.select();
                            }
                            else { // if nothing else works
                                targetElement.value += prefix + postfix;
                                targetElement.focus();
                            }
                        }
                        return false; /* Need this for IE7 problem. See above */
                    });
                }
            }
            $( wrapperNode ).css({
                'float': $( textareaNode ).css( 'float' ),
                marginBottom: $( textareaNode ).css( 'marginBottom' ),
                marginTop: $( textareaNode ).css( 'marginTop' )
            });
            $( wrapperNode ).append( textareaNode );
            $( textareaNode ).css({ margin: '5px 0 0' });
            $( textareaNode ).width( editorWidth - 10 );
            $( siblingNode ).before( wrapperNode );

            /*
            <div class="pfz-editor">
              <div class="pfz-editor-buttons"
                <button>bold</button>
                <button>italic</button>
              </div>
              <textarea></textarea>
            </div>
            */
            //element
        });

        return this;
    };

    function debug( object, defaults, userOptions, options ) {
        // Chrome and Safari will not work without the check for window.console.firebug
        if ( window.console && window.console.firebug ) {
            console.groupCollapsed( object );
            console.log( 'Default options:' )
            console.dir( defaults );
            if ( userOptions ) {
                console.log( 'User options:' )
                console.dir( userOptions );
            }
            else {
                console.log( 'No user options given' );
            }
            console.log( 'Resulting in the following options:' );
            console.dir( options );
            console.groupEnd();
        }
        return;
    };
})(jQuery);

