if (typeof(sonar) != "object" || sonar == null) sonar = {};
//==============================================================================
// @library
//      sonar.event
// @functions
//      addEvent(obj, name, func)
//      removeEvent(obj, name, func)
//      clearEvent()
//==============================================================================
sonar.event =
{
    /***************************************************************************
     * @variable
     *      EVENT_POOL
     **************************************************************************/
    EVENT_POOL : [],



    /***************************************************************************
     * @function
     *      addEvent(obj, name, func)
     * @used
     *      sonar.event.EVENT_POOL
     *      sonar.event.clearEvent()
     **************************************************************************/
    addEvent : function(obj, name, func)
    {
        obj  = obj != null && typeof(obj) == "object" ? obj : null;
        name = name != null && typeof(name) == "string" && name.length > 0 ? name : null;
        func = func != null && typeof(func) == "function" && (!Function.prototype.call || typeof(func.call) == "function") ? func : null;

        if (obj && name && func)
        {
            if (/^on/i.test(name)) name = name.substring(2);

            if (obj.addEventListener)
            {
                obj.addEventListener(name, func, false);
            }
            else
            {
                if (sonar.event.EVENT_POOL.length == 0)
                {
                    window.attachEvent("onunload", sonar.event.clearEvent);
                    sonar.event.EVENT_POOL.push([window, "onunload", sonar.event.clearEvent]);
                }

                obj.attachEvent("on"+name, func);
                sonar.event.EVENT_POOL.push([obj, "on"+name, func]);
            }
        }
    },



    /***************************************************************************
     * @function
     *      removeEvent(obj, name, func)
     **************************************************************************/
    removeEvent : function(obj, name, func)
    {
        obj  = obj != null && typeof(obj) == "object" ? obj : null;
        name = name != null && typeof(name) == "string" && name.length > 0 ? name : null;
        func = func != null && typeof(func) == "function" && (!Function.prototype.call || typeof(func.call) == "function") ? func : null;

        if (obj && name && func)
        {
            if (/^on/i.test(name)) name = name.substring(2);

            if (obj.removeEventListener)
            {
                obj.removeEventListener(name, func, false);
            }
            else
            {
                obj.detachEvent("on"+name, func);
            }
        }
    },



    /***************************************************************************
     * @function
     *      clearEvent()
     * @used
     *      sonar.event.EVENT_POOL
     *      sonar.event.removeEvent(obj, name, func)
     **************************************************************************/
    clearEvent : function()
    {
        while (sonar.event.EVENT_POOL.length > 0)
        {
            sonar.event.removeEvent.apply(sonar.event, sonar.event.EVENT_POOL.pop());
        }
    }
}











/***
 * @function
 *      getElementsByChild(id)
 **/
var getElementsByChild = function(oid) {
    var obj  = /^(object)$/i.test(typeof(oid)) ? oid : document.getElementById(oid);
    var list = [];
    var idx  = 0;

    for (var i=0; obj && i < obj.childNodes.length; i++) {
        if (obj.childNodes[i].nodeType == 1) {
            list[idx++] = obj.childNodes[i];
        }
    }

    return list;
}



/***
 * @function
 *      promoCircuit(id, args)
 * @arguments
 *      tabsParentID
 *      circuitTerm
 *      useFade
 *      fadeOutRatio
 *      fadeOutTerm
 *      fadeInRatio
 *      fadeInTerm
 *      useSlide
 *      slideOutDirection
 *      slideOutDistance
 *      slideOutAbort
 *      slideOutRatio
 *      slideOutTerm
 *      slideInDirection
 *      slideInDistance
 *      slideInAbort
 *      slideInRatio
 *      slideInTerm
 **/
var promoCircuit = function(id, args) {
    sonar.event.addEvent(window, "onload", function() {
        // Arguments
        var c_obj    = document.getElementById(id);
        var c_img    = getElementsByChild(c_obj);
        var c_tab    = getElementsByChild(args.tabsParentID);
        var c_term   = /^[0-9]+$/.test(args.circuitTerm) ? parseInt(args.circuitTerm) : 3000;
        var f_flag   = args.useFade ? args.useFade : false;
        var fo_ratio = /^[0-9]+$/.test(args.fadeOutRatio) ? parseInt(args.fadeOutRatio) : 8;
        var fo_term  = /^[0-9]+$/.test(args.fadeOutTerm) ? parseInt(args.fadeOutTerm) : 30;
        var fi_ratio = /^[0-9]+$/.test(args.fadeInRatio) ? parseInt(args.fadeInRatio) : 8;
        var fi_term  = /^[0-9]+$/.test(args.fadeInTerm) ? parseInt(args.fadeInTerm) : 30;
        var s_flag   = args.useSlide ? args.useSlide : false;
        var so_dir   = /^(top)|(bottom)|(left)|(right)$/i.test(args.slideOutDirection) ? args.slideOutDirection : "left";
        var so_dist  = /^[0-9]+$/.test(args.slideOutDistance) ? parseInt(args.slideOutDistance) : 100;
        var so_abort = /^[0-9]+$/.test(args.slideOutAbort) ? parseInt(args.slideOutAbort) : null;
        var so_ratio = /^[0-9]+$/.test(args.slideOutRatio) ? parseInt(args.slideOutRatio) : 8;
        var so_term  = /^[0-9]+$/.test(args.slideOutTerm) ? parseInt(args.slideOutTerm) : 30;
        var si_dir   = /^(top)|(bottom)|(left)|(right)$/i.test(args.slideInDirection) ? args.slideInDirection : "right";
        var si_dist  = /^[0-9]+$/.test(args.slideInDistance) ? parseInt(args.slideInDistance) : 100;
        var si_abort = /^[0-9]+$/.test(args.slideInAbort) ? parseInt(args.slideInAbort) : null;
        var si_ratio = /^[0-9]+$/.test(args.slideInRatio) ? parseInt(args.slideInRatio) : 8;
        var si_term  = /^[0-9]+$/.test(args.slideInTerm) ? parseInt(args.slideInTerm) : 30;

        // Variables
        var flag  = true;
        var timer = null;
        var max   = c_img.length > c_tab.length ? c_img.length : c_tab.length;
        var prev  = 0;
        var next  = 0;

        // Initialize
        if (!window.timers) window.timers = [];

        for (var i=0; i < c_img.length; i++) c_img[i].style.display = (i == 0 ? "" : "none");

        if (!c_obj.style.position) c_obj.style.position = "relative";
        if (!c_obj.style.width)    c_obj.style.width    = c_obj.offsetWidth + "px";
        if (!c_obj.style.height)   c_obj.style.height   = c_obj.offsetHeight + "px";
        if (!c_obj.style.overflow) c_obj.style.overflow = "hidden";
        if (!c_obj.style.zIndex)   c_obj.style.zIndex   = 0;

        for (var i=0; i < max; i++) {
            if (c_img.length > i) {
                c_img[i].style.position = "absolute";
                c_img[i].style.zIndex   = max - i - 1;
                c_img[i].onmouseover    = function() { window.timers[id].pause(); }
                c_img[i].onmouseout     = function() { window.timers[id].resume(); }
            }

            if (c_tab.length > i) {
                c_tab[i].idx         = i;
                c_tab[i].className   = (i == 0 ? "on" : "");
                c_tab[i].onmouseover = function() { window.timers[id].pause(); window.timers[id].select(this.idx); }
                c_tab[i].onmouseout  = function() { window.timers[id].resume(); }
                c_tab[i].onclick     = function() { window.timers[id].stop(); window.timers[id].select(this.idx); }
            }
        }

        // Inner Select Funcion
        var selectFunc = function(idx, rev) {
            prev = next;
            next = idx;

            for (var i=0; i < max; i++) {
                if (c_img.length > i) {
                    var z = (max - i - 1) + next;

                    c_img[i].style.display = (i == next ? "" : "none");
                    c_img[i].style.zIndex  = (z >= max ? z - max : z);
                }

                if (c_tab.length > i) {
                    c_tab[i].className = (i == next ? "on" : "");
                }
            }

            if (f_flag) {
                promoFade(c_img[prev], {
                    type  : "out",
                    ratio : fo_ratio,
                    term  : fo_term
                });

                promoFade(c_img[next], {
                    type  : "in",
                    ratio : fi_ratio,
                    term  : fi_term
                });
            }

            if (s_flag) {
                promoSlide(c_img[prev], {
                    type      : "out",
                    direction : (rev ? si_dir : so_dir),
                    distance  : so_dist,
                    abort     : so_abort,
                    ratio     : so_ratio,
                    term      : so_term
                });

                promoSlide(c_img[next], {
                    type      : "in",
                    direction : (rev ? so_dir : si_dir),
                    distance  : si_dist,
                    abort     : si_abort,
                    ratio     : si_ratio,
                    term      : si_term
                });
            }
        }

        // Inner Reflect Function
        var reflectFunc = function() {
            selectFunc(next+1 < max ? next+1 : 0);

            timer = setTimeout(reflectFunc, c_term);
        }

        // Global Event Function
        window.timers[id] = {
            pause : function() {
                if (flag) clearTimeout(timer);
            },

            resume : function() {
                if (flag) timer = setTimeout(reflectFunc, c_term);
            },

            stop : function() {
                if (flag) { clearTimeout(timer); flag = false; }
            },

            select : function(idx) {
                if (next != idx) selectFunc(idx, false);
            },

            prev : function() {
                window.timers[id].stop();

                selectFunc(next-1 > -1 ? next-1 : max-1, true);
            },

            next : function() {
                window.timers[id].stop();

                selectFunc(next+1 < max ? next+1 : 0, false);
            }
        }

        if (max > 0) timer = setTimeout(reflectFunc, c_term);
    });
}



/***
 * @function
 *      promoFade(oid, args)
 * @arguments
 *      type
 *      ratio
 *      term
 **/
var promoFade = function(oid, args) {
    // Arguments
    var obj   = /^(object)$/i.test(typeof(oid)) ? oid : document.getElementById(oid);
    var type  = args.type;
    var ratio = /^[0-9]+$/.test(args.ratio) ? parseInt(args.ratio) : 8;
    var term  = /^[0-9]+$/.test(args.term) ? parseInt(args.term) : 30;

    // Variables
    var flag  = /^(in)|(out)$/i.test(type);
    var opa   = type == "in" ? 0 : 100;

    // Initialize
    if (flag) {
        obj.style.position = "absolute";
    }

    // Inner Reflect Function
    var reflectFunc = function() {
        if (type == "in") {
            flag = opa < 100;

            if (flag) {
                opa = opa + Math.ceil((100 - opa) / ratio);
                opa = opa > 80 ? 100 : opa;
            }
        }
        else {
            flag = opa > 0;

            if (flag) {
                opa = opa - Math.ceil((100 + opa) / ratio);
                opa = opa < 20 ? 0 : opa;
            }
        }

        if (flag) {
            obj.style.filter = "alpha(opacity=" + opa + ")";
            obj.style.MozOpacity = opa / 100;
            obj.setAttribute("opacity", opa / 100);
        }

        if (flag) {
            setTimeout(reflectFunc, term);
        }
        else {
            if (type == "out") obj.style.display = "none";
        }
    }

    if (flag) {
        obj.style.display = "";
        reflectFunc();
    }
}



/***
 * @function
 *      promoSlide(oid, args)
 * @arguments
 *      type
 *      direction
 *      distance
 *      abort
 *      ratio
 *      term
 **/
var promoSlide = function(oid, args) {
    // Arguments
    var obj    = /^(object)$/i.test(typeof(oid)) ? oid : document.getElementById(oid);
    var type   = args.type;
    var dir    = args.direction;
    var dist   = /^[0-9]+$/.test(args.distance) ? parseInt(args.distance) : 0;
    var abort  = /^[0-9]+$/.test(args.abort) ? parseInt(args.abort) : dist;
    var ratio  = /^[0-9]+$/.test(args.ratio) ? parseInt(args.ratio) : 8;
    var term   = /^[0-9]+$/.test(args.term) ? parseInt(args.term) : 30;

    // Variables
    var flag   = /^(in)|(out)$/i.test(type) && /^(top)|(bottom)|(left)|(right)$/i.test(dir) && dist != 0;
    var from   = 0;
    var to     = 0;
    var sum    = 0;

    // Initialize
    if (flag) {
        obj.style.position = "absolute";
        obj.style.top      = "0px";
        obj.style.left     = "0px";

        if (type == "in") {
            switch (dir) {
                case "top"    : from = -dist; to = 0; break;
                case "bottom" : from = dist;  to = 0; break;
                case "left"   : from = -dist; to = 0; break;
                case "right"  : from = dist;  to = 0; break;
            }
        }
        else {
            switch (dir) {
                case "top"    : from = 0; to = -dist; break;
                case "bottom" : from = 0; to = dist;  break;
                case "left"   : from = 0; to = -dist; break;
                case "right"  : from = 0; to = dist;  break;
            }
        }
    }

    // Inner Reflect Function
    var reflectFunc = function() {
        if (flag) {
            if (from < to) {
                sum  += Math.ceil((to - from) / ratio);
                from += Math.ceil((to - from) / ratio);
            }
            else {
                sum  += Math.ceil((from - to) / ratio);
                from -= Math.ceil((from - to) / ratio);
            }

            if (dir == "top" || dir == "bottom") {
                obj.style.top = from + "px";
            }
            else {
                obj.style.left = from + "px";
            }

            flag = (from != to && abort > sum);

            if (flag) {
                setTimeout(reflectFunc, term);
            }
            else {
                if (type == "out") obj.style.display = "none";
            }
        }
    }

    if (flag) {
        obj.style.display = "";
        reflectFunc();
    }
}