/**
 * @requires    jquery 1.2.6
 * @requires    jquery ui, draggable, droppable
 * @requires    repl_table.js
 *
 * $Id: create.js 8235 2010-07-05 16:02:20Z rs $
 */


var Keywords = [];

$(document).ready(function(){

    // Tabellen-Kopfzeilen mit Drag&Drop verschiebbar machen
    $('table.lines th').draggable({
        helper:'clone',
            revert: 'invalid',
            cursorAt: {bottom:2, right:2}
        })
        // ... und alle Schlüsselwörter merken
        .each(function(){
            Keywords.push($(this).text());
        });

    ImageTextEdit.prepare();

    // Links dargestellte Seiten des Kalenders: Klick
    // zeigt Eingabemöglichkeit für das dort hinterlegte Motiv.
    $('div.calendar-page').bind("click", function(event) {
        EditMotifManager.loadPage(event,this)
    });
    if($('div.current').length != 0)
      $('div.current').trigger("click");
    else   
      $('div#calendar-page_0').trigger("click");
      
      
    // Rechts dargestellte List der Möglichen Motive,
    // Klick übernimmt Motiv auf aktuelle Seite
    $('div.motiv-select').bind("click", function(event) {
        EditMotifManager.setMotif(event,this)
    });


    });

ImageTextEdit = {

    maxAlternativeLines: 2,            // Mögliche Anzahl der Alternativzeilen

    navKeys: [37,38,39,40,36,35],    // Cursor und home/end-Keycodes

    /**
     * Im Motiv-Formular Eingabefeld die Proof-Funktionalität zuweisen
     */
    prepare: function() {
        $('input.motivFormular').each(function() {
            this.handler = new ImageTextEdit.handler(this);
        });

        // wurde kein Vorschaubild mitgegeben, eines anfordern
        if(document.getElementById("motivimage") && $("#motivimage")[0].src =="") {
             EditMotifManager.makePreview();
        }

        // Auf welcher Seite sind wir gerade?
        // Aus dem Formular auslesen
	if ( $("#motivText")[0] ) {
            EditMotifManager.currentPage = $("#motivText")[0]["page"].value;
	}
    },

    // Eingabezeilen, evtl auch neu nachgeladene, werden mit
    // verschiedenen Funktionen ausgestattet
    handler: function(node) {

        var self = this; // Das aktuelle Objekt für verschiedene Aufrufe speichern

        this.node = node;
        this.text = this.node.value;

        // das <div class="line"> um die Eingabezeile herum
        this.container = $(node).parent("div")[0];

        this.id = this.node.id.match(/line_(\d+)-(\d+)/);    // Zeilennummer und Subzeilennummer merken
        this.line = this.id[1]-1;

        this.child = false;         // hat momentan keine Alternativ-Zeilen

        this.foundKeyword = false; // enthält im Moment kein Schlüsselwort


        // Verbindung zum Parent herstellen:
        if(this.id[2] > 0) {              // Es ist eine Alternativzeile
            //console.log(this.id[2]-1 + ": parent informiert!");
            $("#line_"+this.id[1]+"-"+ (parseInt(this.id[2])-1))[0].handler.child = this.node;
        }


        // Um welches Motiv handelt es sich hier? Aus dem <form> auslesen
        var parentForm = $(this.node).parents("form")[0];
        this.motiveId = parseInt($(parentForm).find('input[name=motivid]').val());
        this.page = $(parentForm).find('input[name=page]').val();

        // hinten status-Platzhalter einfügen
        this.statusDisplay = $('<span class="status"></span>');
        $(this.node).after(this.statusDisplay);

        this.status = ''; //false;

        // Die Eingabezeilen erhalten den Drop
        $(this.node).droppable({
            accept: 'table.lines th',
            hoverClass: 'dropHover',

            // Der Inhalt des Kabellenkopfes wird in <...> eingefügt
            drop: function(event, ui) {
                $(self.node)[0].value += '<' + $(ui.draggable).text() + '> ';
                $(self.node).trigger("change");
            }
        });

        // bei Änderung/Tastendruck
        $(this.node).bind("change keyup", function(event){self.checkLine(event)});

        /**
         * checkLine
         *
         * Prüft, ob ein Schlüsselwort in der Eingabezeile steht.
         * Wenn ja, neue Alternativ-Zeile erstellen.
         * Außerdem immer Proof aufrufen!
         */
        this.checkLine = function(event) {

            // Wenn eine Cursor-Taste gedrückt wurde, alles sein lassen
            if(event) {
                for(var i=0; i<ImageTextEdit.navKeys.length; i++) {
                    if(ImageTextEdit.navKeys[i] == event.keyCode) return;
                }
            }


            // es wird gesucht nach "<Schlüsselwort>" im eingabefeld,
            // aber nur für Wörter, die auch in einer <th> stehen!
            this.foundKeyword = false;
            for(var i=0; i<Keywords.length; i++) {
                if(this.node.value.search('<'+ Keywords[i] +'>') != -1) {
                    this.foundKeyword = true;
                    break;
                }
            }

            // wurde ein Schlüsselwort gefunden ...
            if(this.foundKeyword) {

                // keine Altertnativzeile vorhanden und das Maximum an Alternativzeilen
                // noch nicht erreicht
                if(this.child==false && (this.id[2] < ImageTextEdit.maxAlternativeLines)) {
                    var altLine = ImageTextEdit.create(this.id);
                    altLine.firstChild.handler = new ImageTextEdit.handler(altLine.firstChild);
                    $(this.container).append(altLine);
                    $(altLine).slideDown();

                } else if (this.id[2] < ImageTextEdit.maxAlternativeLines) { // Alternativzeile wurde bereits angelegt,
                    //console.log(this.child.handler);
                    $(this.child.handler.container).slideDown();   // nur noch Einblenden
                }
            } else {                                // es ist kein Schlüsselwort vorhanden, aber

                if(this.child) {                    // es ist eine Alternativzeile vorhanden!
                    $(this.child.handler.container).slideUp(); // Dann muss die ausgeblendet werden.
                }
            }

            // Proof starten mit dem ganzen Objekt.
            this.text = this.node.value;
            Proof.run(this);
            // Proof.run() bereitet die Proof-Routinen vor.
            // Wenn alles geladen ist, wird in diesem Objekt die
            // Methode "proof" aufgerufen.
        }

        // Status-Feld hinter der Eingabezeile setzen
        this.setStatus = function(stat) {
            switch(stat) {
                case "loading":                                       // Status wird auf "geladen" gesetzt:
                    $(this.statusDisplay).addClass("loading");        // Spinner anzeigen
                    setTimeout(function(){self.checkLine()}, 2000);   // und in 2 Sekunden nochmal prüfen
                    break;

                case "ready":                                        // Laden beendet:
                    $(self.statusDisplay).removeClass("loading");    // Spinner löschen
                    break;

                default:                                             // Ansonsten:
                  $(self.statusDisplay).removeClass("loading");    // Spinner löschen
                  self.status = stat;                            // Text durchreichen
            }
	    $(this.statusDisplay).html(self.status);
        }

        // Prüfung der Länge für die Anzeige
        this.reportLength = function(length) {
            if(length <= maxWidthL[this.motiveId][this.line]) {
                var perc = Math.round((length/maxWidthL[this.motiveId][this.line])*100);
                var bargraph = '<div class="barBg"><div class="bar" style="width:'+perc+'%"></div></div>'+perc+'%';
		this.setStatus(bargraph);
            } else {
                var perc = Math.round((length/maxWidthL[this.motiveId][this.line])*100);
                var bargraph = '<div class="barBg"><div class="bar err" style="width:100%"></div></div>'+perc+'%';
                this.setStatus(bargraph);
            }
        }

    /**
     * proof: ersetzt nicht mögliche Buchstaben und führt die Längenprüfung durch
     *
     * Diese Funktion wird von "außerhalb" aus dem Proof-Objekt aufgerufen, da zuerst
     * externe Datenquellen global nachgeladen werden müssen.
     *
     * Eventuell vorhandene Schlüsselwörter müssen beim Ersetzen und bei der
     * Längenprüfung ignoriert werden. Dazu wird der Text des Eingabefeldes an den
     * Schlüsselwortgrenzen in beliebig viele Teile geteilt, diese Teile geprüft und
     * hinterner wieder zusammengesetzt.
     */

    this.proof = function() {

        var textParts = new Array();     // hierin werden gleich die Teile des Textes gespeichert

        var seek = 0;                            // an dieser Stelle im Text wird gerade gearbeitet
        var found = 0;                           // letzte Fundstelle
        var look = 0;                            // aktuelle Suchposition

        while(seek != -1) {
             seek = this.text.indexOf('<', look);    // nach möglichem Anfang eines Schlüsselwortes suchen

             if(seek != -1) {                                // Es wurde ein < gefunden!

                var keywordFound = false;

                for(var i=0; i < Keywords.length; i++) {    // alle Schlüsselwörter in Betracht ziehen

                    if (this.text.indexOf(Keywords[i]+">", look) == (seek+1)) {    // Keyword gefunden!!

                        var plainText = this.text.slice(found, seek);                // Text vor dem Keyword

                        if(plainText.length>0) {                                            // im Array speichern
                            textParts.push({keyword: false, text: plainText});
                        }

                        // Endposition des Keywords:
                        //           start  Länge Keyword        < vorne, > hinten
                        var endPos = seek + Keywords[i].length + 2;

                        var keyword = this.text.slice(seek, endPos);

                        textParts.push({keyword: true, text: keyword});                // keyWord speichern

                        found = endPos; // jetzt vom Ende des gefundenen Keywords an weitersuchen
                        look = endPos;
                        keywordFound = true;
                        break;
                    }
                }

                if(!keywordFound) {    // falls nach dem < doch kein Schlüsselwort kam ...
                    look = seek+1;    // von nun an nach dem gefundenen < weitersuchen
                }
            }
        }

        // Was übrig ist muss wohl plainText sein
        var plainText = this.text.slice(found);

        if(plainText.length>0) {                                       // sofern was da war
             textParts.push({keyword: false, text: plainText});        // das speichern
        }

        var self = this;                                               // das alte Binding-Problem ...
        var length = 0;
        var correctedText = '';

        for(var i=0; i<textParts.length; i++) {

            if(!textParts[i].keyword) {
                textParts[i].text = Proof.replace(textParts[i].text, this);
                length += Proof.checkLength(textParts[i].text, this);
            }
            correctedText += textParts[i].text;
        }

        this.text = correctedText;
        this.node.value = this.text;

        this.reportLength(length);
    };

    // Nachdem alles initialisiert ist, die Eingabe das erste Mal prüfen.
    // Kleiner Timeout, damit eventuell vorhandene children sich noch melden können.
    setTimeout(function(){self.checkLine();},100);

    },

    /**
     * create: Erzeugt Alternative Eingabezeile
     */
    create: function(id) {
        // neue ID ...
        id = "line_" + id[1] + "-" + (parseInt(id[2])+1);
        return $('<div class="altLine"><input class="motivFormular" type="text" name="'+id+'" id="'+id+'" /></div>').hide()[0];
    }
}

