/**
 * Kniznica RainJS
 *
 * Obsah:
 *   trieda   RForm       validacia formularov
 *   trieda   RCookies    praca s cookies
 *   funkcia  rDump       vrati dump objektu
 *   funkcia  rPrint      vypise dump objektu do dokumentu
 *   funkcia  rAlert      zobrazi dump objektu v alert okne
 *   funkcia  rOpenImage  otvori obrazok v novom pop-up okne
 *
 * Kniznica RainJS je zavisla na kniznici Prototype (otestovane s verziou 1.5.0),
 * ktora je takisto OpenSource, volne k dispozicii na http://www.prototypejs.org.
 *
 *
 * RainJS - JavaScript Utility Library
 *
 * Copyright (C) 2005 - 2007  Oto Komiňák (www.oto.kominak.sk)
 *
 *
 * LICENSE:
 *
 * This library is free software; you can redistribute it and/or modify it under the terms
 * of the GNU Lesser General Public License as published by the Free Software Foundation;
 * either version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 * See the GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License along with this
 * library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
 * Boston, MA 02111-1307 USA
 *
 * @package     RainJS
 * @author      Oto Komiňák
 * @copyright   2005-2007 Oto Komiňák
 * @link        http://www.oto.kominak.sk
 * @license     http://www.opensource.org/licenses/lgpl-license.php GNU LGPL
 * @version     1.0
 * @since       1.0
 * @filesource
 */



/**
 * Trieda na validaciu formularov
 */
function RForm(objName, formName) {

    this.objName  = objName;
    this.formName = formName;

    this.fields         = new Array;
    this.errors         = 0;
    this.modified       = false;
    this.watchingUnload = false;

    /**
     *  Pole jednoduchych datovych typov
     *
     * Pole obsahuje regularne vyrazy pre validaciu emailov, telefonnych cisel, ...
     * Ostatne zlozitejsie datove typy su kontrolovane samostatne: integer, text, regex.
     * Pre podrobnosti vid funkciu validateField().
     */
    this.regex = {
        "empty":        /^\s*$/,
        "email":        /^[^@]+@[^@.]+\.[^@]*\w\w$/,
        "mobile":       /^0[0-9]{2,3} [0-9]{3} [0-9]{3}$/,
        //"mobileIntl":   /^\+[0-9]{2,3} [0-9]{3} [0-9]{3}$/,
        "phone":        /^\+?[0-9\ ]+$/
    };


    /**
     * Nastavi obsluzne funkcie vsetkym vsetupnym poliam spomenutym v this.fields.
     */
    this.setHandlers = function() {
        var name;
        for (name in this.fields) {
            if (!name) continue;
            var input = $(name);
            var div   = input.parentNode;

            eval("input.onchange = function() { " + this.objName + ".validateField(this); };");

            var children = div.getElementsByTagName("span");
            if (children.length >= 1) {
                this.fields[name].spanText = children[0].innerHTML;
            }
        }
    }


    /**
     * Funkcia zapne kontrolu nechceneho opustenia formulara
     *
     * Nechcene opustenie formualra nastane, ak uzivatel zmenil niektore zo
     * sledovanych vstupnych poli, a bez ulozenia zmien opusta stranku.
     */
    this.watchUnload = function () {
        if (watchUnload) {
            this.watchingUnload = true;
            eval(
                "window.onunload = function() { " +
                "   if ((" + this.objName + ".modified) && (confirm(I18N.RainJS.leaveUnsaved))) { " +
                "       $(\"" + this.formName + "\").submit(); " +
                "   } " +
                "}"
            );
        }
    }


    /**
     * Nastavi status vstupnemu polu: ok / error
     */
    this.setStatus = function(div, ok, message) {
        div = $(div);
        div.removeClassName("input-ok");
        div.removeClassName("input-error");
        if (ok) {
            div.addClassName("input-ok");
        } else {
            div.addClassName("input-error");
            this.errors += 1;
        }

        // Span element, ktory obsahuje informacie o validite input boxu
        var children = div.getElementsByTagName("span");
        if (children.length >= 1) {
            $(children[0]).update(message);
        }

        return ok;
    }


    /**
     * Skontroluje validitu vstupneho pola
     */
    this.validateField = function(input) {
        // Nastavenia z pola this.fields relevantne pre tento div
        var field = this.fields[input.id];

        // Volanie uzivatelskeho handleru
        if (field.onchange) {
            field.onchange();
            field = this.fields[input.id];
        }

        // Div element, ktory obsahuje label, input a span
        var div = input.parentNode;

        // Hodnota pola bez medzier na zaciatku a na konci
        var value = input.value.replace(/^\s+|\s+$/g, '');
        //value = trim(input.value);

        this.modified = true;

        //if (this.regex.empty.test(input.value)) {
        if (value == "") {
            return this.setStatus(div, !field.required, field.spanText);
            if (field.required) {
                return this.setStatus(div, false, I18N.RainJS.error);
            } else {
                return this.setStatus(div, true, I18N.RainJS.optional);
            }
        }

        // Najprv skusime, ci nejde o jednoduchy typ z this.regex.
        if (this.regex[field.type]) {
            if (this.regex[field.type].test(value)) {
                return this.setStatus(div, true, I18N.RainJS.ok);
            } else {
                var messageId = "error";
                switch (field.type) {
                    case "email": messageId = "wrongEmail";     break;
                    case "phone": messageId = "error";          break;
                }
                return this.setStatus(div, false, I18N.RainJS[messageId]);
            }
        }

        // Dalej skusime, ci nejde o specialny typ "regex", kde je nutne
        // uviest specificky regularny vyraz.
        if (field.type == "regex") {
            if (field.regex.test(value)) {
                return this.setStatus(div, true, I18N.RainJS.ok);
            } else {
                return this.setStatus(div, false, I18N.RainJS.error);
            }
        }

        // Typ "text"
        if (field.type == "text") {
            if ((field.min != null) && (value.length < field.min)) {
                return this.setStatus(div, false, I18N.RainJS.minLength + " " + field.min);
            }
            if ((field.max != null) && (value.length > field.max)) {
                return this.setStatus(div, false, I18N.RainJS.maxLength + " " + field.max);
            }
            return this.setStatus(div, true, I18N.RainJS.ok);
        }

        // Typ "integer" (cele cislo)
        if (field.type == "integer") {
            var regex = /^-?[0-9]+$/;
            if (!regex.test(value)) {
                return this.setStatus(div, false, I18N.RainJS.wrongInteger);
            }
            var n = parseInt(value);
            if ((field.min != null) && (n < field.min)) {
                return this.setStatus(div, false, I18N.RainJS.min + " " + field.min);
            }
            if ((field.max != null) && (n > field.max)) {
                return this.setStatus(div, false, I18N.RainJS.max + " " + field.max);
            }
            return this.setStatus(div, true, I18N.RainJS.ok);
        }

        // Typ "float" (desatinne cislo s bodkou alebo ciarkou)
        if (field.type == "float") {
            var regex = /^-?[0-9]*[,.]?[0-9]+$/;
            if (!regex.test(value)) {
                return this.setStatus(div, false, I18N.RainJS.wrongInteger);
            }
            var n = parseFloat(value.replace(/,/, '.'));
            if ((field.min != null) && (n < field.min)) {
                return this.setStatus(div, false, I18N.RainJS.min + " " + field.min);
            }
            if ((field.max != null) && (n > field.max)) {
                return this.setStatus(div, false, I18N.RainJS.max + " " + field.max);
            }
            return this.setStatus(div, true, I18N.RainJS.ok);
        }

        return true;
    }


    this.validateAllFields = function (showAlert) {
        this.errors = 0;

        if (this.watchingUnload) {
            window.onunload = function() { }
        }

        var name, input;
        for (name in this.fields) {
            if (!name) continue;
            input = $(name);
            input.onchange(input);
        }

        if (this.errors > 0) {
            if (showAlert) {
                alert(I18N.RainJS.checkForm);
            }
            return false;
        } else {
            return true;
        }
    }

}


/**
 * Trieda na pracu s cookies
 */
function RCookies() {

    this.getCookie = function (name)  {
        var start = document.cookie.indexOf( name + "=" );
        var len = start + name.length + 1;
        if ( ( !start ) && ( name != document.cookie.substring( 0, name.length ) ) ) {
            return null;
        }
        if ( start == -1 ) return null;
        var end = document.cookie.indexOf( ';', len );
        if ( end == -1 ) end = document.cookie.length;
        return unescape( document.cookie.substring( len, end ) );
    }


    this.setCookie = function (name, value, expires, path, domain, secure) {
        var today = new Date();
        today.setTime( today.getTime() );
        if ( expires ) {
            expires = expires * 1000 * 60 * 60 * 24;
        }
        var expires_date = new Date( today.getTime() + (expires) );
        document.cookie = name+'='+escape( value ) +
            ( ( expires ) ? ';expires='+expires_date.toGMTString() : '' ) + //expires.toGMTString()
            ( ( path ) ? ';path=' + path : '' ) +
            ( ( domain ) ? ';domain=' + domain : '' ) +
            ( ( secure ) ? ';secure' : '' );
    }

    this.deleteCookie = function (name, path, domain) {
        if ( getCookie( name ) ) document.cookie = name + '=' +
                ( ( path ) ? ';path=' + path : '') +
                ( ( domain ) ? ';domain=' + domain : '' ) +
                ';expires=Thu, 01-Jan-1970 00:00:01 GMT';
    }
}


/**
 * Skryvacie administracne menu
 */
function RAdminMenu(obj, div, leftPadding) {

    eval("$('" + div + "').onmouseover = function() { " + obj + ".menuOut(); };");
    eval("$('" + div + "').onmouseout  = function() { " + obj + ".menuIn();  };");

    this.obj        = obj;
    this.div        = $(div);

    this.timerOut   = null;
    this.timerIn    = null;

    this.interval   = 10;
    this.dx         = 10;

    this.leftPos        = -this.div.getWidth() + leftPadding;
    this.div.style.left = this.leftPos + "px";


    // Odkrytie menu
    this.menuOut = function () {
        if (this.timerIn) clearInterval(this.timerIn);

        this.timerOut = setInterval(this.obj + ".menuOutMotion()", this.interval);
    }


    // Elementarny posun pre menuOut()
    this.menuOutMotion = function () {
        if (parseInt(this.div.style.left) < 0) {
            this.div.style.left = parseInt(this.div.style.left) + this.dx + "px";

        } else if (this.timerOut) {
            this.div.style.left = "0px";
            clearInterval(this.timerOut);
        }
    }


    // Skrytie menu
    this.menuIn = function () {
        clearInterval(this.timerOut);
        this.timerIn = setInterval(this.obj + ".menuInMotion()", this.interval);
    }


    // Elementarny posun pre menuIn()
    this.menuInMotion = function () {
        if (parseInt(this.div.style.left) > this.leftPos) {
            this.div.style.left = parseInt(this.div.style.left) - this.dx + "px";

        } else if (this.timerIn) {
            this.div.style.left = this.leftPos + "px";
            clearInterval(this.timerIn);
        }
    }
}


/**
 * Vygeneruje dump objektu
 */
function rDump(obj, name, html, indent, depth) {
    var nl = "\n";

    if (depth > 10) {
        return indent + name + ": <Maximum Depth Reached>" + nl;
    }

    if (typeof obj == "object") {
        var child = null;
        var output = indent + name + nl;
        indent += html ? "&nbsp;&nbsp;&nbsp;&nbsp;" : "    ";

        for (var item in obj) {
            try {
                child = obj[item];
            } catch (e) {
                child = "<Unable to Evaluate>";
            }
            if (typeof child == "object") {
                output += rDump(child, item, html, indent, depth + 1);
            } else {
                output += indent + item + ": " + child + nl;
            }
        }
        return output;

    } else {
        return obj;
    }
}


/**
 * Zobrazi dump objektu v alert okne
 */
function rAlert(obj) {
    alert(rDump(obj, "", false, "", 0));
}


/**
 * Vypise dump objektu do dokumentu
 */
function rPrint(obj) {
    document.write("<div style=\"text-align: left\"><pre>" + rDump(obj, "", true, "", 0) + "</pre></div>");
}


/**
 * Otvori obrazok (resp. akukolvek url) v novom pop-up okne
 */
function rOpenImage(url) {
    window.open(url, 'w', 'toolbar=no,location=no,directories=no,status=no,menubar=no,scrollbars=no,resizable=no,copyhistory=no,width=660,height=660');
}


/**
 * Prida riadkom v table.cms-listing efekt pre mouse over
 */
function rTableMouseOver() {
    var tables = document.getElementsByClassName("cms-listing");

    for (var i = 0; i < tables.length; i++) {
        var rows = tables[i].getElementsByTagName("tr");
        var j = 0;

        var firstRowParent = rows[0].parentNode.tagName;
        if ((firstRowParent == "THEAD") || (firstRowParent == "thead")) j++;

        for (; j < rows.length; j++) {
            rows[j].onmouseover = function () {
                this.addClassName("mouseover")
            }
            rows[j].onmouseout = function () {
                this.removeClassName("mouseover");
            }
        }
    }
}


/**
 * Osetri MSIE Flash bug/feature.
 */
function rFixFlash() {
    var n = navigator.userAgent;
    var w = n.indexOf("MSIE");

    if ((w > 0) && (parseInt(n.charAt(w + 5)) > 5)) {
        var T = ["object", "embed", "applet"];
        for (var j = 0; j < 2; j++) {
            var E = document.getElementsByTagName(T[j]);
            for (var i = 0; i < E.length; i++) {
                var P = E[i].parentNode;
                var H = P.innerHTML;
                P.removeChild(E[i]);
                P.innerHTML = H;
            }
        }
    }
}


