var Vs =
{
    selected : "",
    working : false,
    comboing : false,
    started : false,

    mode : "single",

    turn : 1, // current turn
    maxturn : -1,

    counter : -1, // current timer
    cystal : null, // periodical executer
    delay : 2, // delay in seconds

    data : null,
    log : null,

    select : function()
    {
        // hide
        $A($$(".battle .selected")).each(function(element)
            {
                element.removeClassName("selected");
            });

        // show new fighter
       var element = $("Fighter" + Vs.selected);

        if (element)
        {
            element.addClassName("selected");
            element.hide();
            new Effect.Appear(element, { duration : 0.5,
                                             afterFinish : Vs.end });
        }
    },

    end : function()
    {
        Vs.working = false;
    },


    start : function(response)
    {
        Vs.started = true;

        // init animation data
        Vs.data = response.data;

        // sanitize configuration
        if (!System.isset(Vs.data.config))
        Vs.data.config = { animation : 0, log : 0 };

        /*
        if ($("VsSelect"))
            $("VsSelect").hide();
        */
        $("VsMsg").setStyle({ height : "300px" });

        if (Vs.data.config.animation == 2)
        {
            // skip animation
            Vs.stop();
        }
        else
        {
            // start animation
            Vs.init();
            Vs.animate();

            // start paused
            if (Vs.data.config.animation == 1)
            Vs.pause();
        }
    },


    init : function()
    {
        Vs.clear();

        var pc = {};
        var i = 0;

        var t = new Template($("VsPlayerTemplate").value);
        Vs.data.teams.each(function(player)
        {
            var e = $("VsTeam" + player.side);
            e.insert(t.evaluate
                     ({
                         t_name : player.name,
                             t_avatar : player.avatar,
                             t_level : player.level,
                             t_p : i
                             })
                     );

            if (System.isset(pc["t" + player.side]))
                {
                    pc["t" + player.side]++;
                    Vs.mode = "multi";
                }
            else
                pc["t" + player.side] = 1;

            i++;
        }); // end iteration team
            
    },

    // update player status
    status : function(data, i, active)
    {          
        var ohp = $("Player" + i + "Hp").innerHTML;
        var occ = $("Player" + i + "CCount").innerHTML;

        // no need to update if already defeated
        /*
        if ((ohp <= 0 && ohp != "-") || (occ <= 0 && occ != "-"))
            return false;
        */

        // show attacked player
        $("Player" + i + "PName").removeClassName("melee");
        $("Player" + i + "PName").removeClassName("willpower");

        if (ohp > data.hp)
        $("Player" + i + "PName").addClassName("melee");

        if (occ != "-" && i != active && occ > data.card)
            $("Player" + i + "PName").addClassName("willpower");


        // update status
        $("Player" + i + "Hp").update(data.hp);
        $("Player" + i + "MaxHp").update(data.maxhp);
        
        data.hp = (data.hp < 0) ? 0 : data.hp;
        
        var base = parseInt(data.maxhp);
            
        data.ac = (data.ac > base) ? base : data.ac;
        data.wd = (data.wd > base) ? base : data.wd;

        // bars            
        $("Player" + i + "BarHp").setStyle({width : Math.floor(data.hp * 100 / data.maxhp) + "%"});
        $("Player" + i + "BarArmor").setStyle({width : Math.floor(data.ac * 100 / base) + "%"});
        $("Player" + i + "BarWard").setStyle({width : Math.floor(data.wd * 100 / base) + "%"});

        if (Math.floor(data.hp * 100 / data.maxhp) < 30)
            $("Player" + i + "BarHp").addClassName("critical");
        else
            $("Player" + i + "BarHp").removeClassName("critical");

        $("Player" + i + "CCount").update(data.card);

        if (data.hp <= 0 || data.card <= 0) // defeated player
        {
            $("Player" + i + "Avatar").setStyle({ opacity : 0.2 });
            $("Player" + i + "Hp").update("0");
        }
        else
        $("Player" + i + "Avatar").setStyle({ opacity : 1 });

    },

    unfocus : function()
    {
        $("VsFocus0").hide();
        $("VsFocus1").hide();
    },

    update : function()
    {
        var active = Vs.data.turns[Vs.turn].active;
        var card = Vs.data.turns[Vs.turn].card;
        var quote = Vs.data.turns[Vs.turn].ambiance;
        var focus = Vs.data.turns[Vs.turn].focus;

        // focus
        Vs.unfocus();
        $A(focus).each(function(e, i)
        {
            var f = $("VsFocus" + i);
            var g = $("Player" + e + "Avatar"); 
            if (f && g)
                {
                    System.showAt(f, g);
                }
        });

        // update player status
        Vs.data.turns[Vs.turn].players.each(function(e, i) { Vs.status(e, i, active); });


        // update active card
        $("Player" + active + "CName").update(card.name);
        $("Player" + active + "CDesc").update(Vs.data.turns[Vs.turn].effect);

        switch (Vs.mode)
        {
        case "single" :
            $("Player" + active + "CRune1").className = "rune rune_l rune_" + card.rune1;
            $("Player" + active + "CRune2").className = "rune rune_r rune_" + card.rune2;
            $$(".vs .card_hr").each(function(element, index)
            {
                element.setStyle({ opacity : ((index == active) ? 1 : 0.2) });
            });
            break;
        case "multi" : 
            $("Player" + active + "CRune1").className = "minirune minirune_l minirune_" + card.rune1;
            $("Player" + active + "CRune2").className = "minirune minirune_r minirune_" + card.rune2;
            $$(".vsm .card_lr").each(function(element, index)
            {
                element.setStyle({ opacity : ((index == active) ? 1 : 0.2) });
            });
            break;
        default:
        }


        // combo 
        if (card.combo == true)
        {
            Vs.combo(card, Vs.data.turns[Vs.turn].effect);
        }

        
        if (quote.length > 0)
            Dialog.show(quote, $("Player" + active + "Avatar"));
        else
            Dialog.hide();

        // update log
        System.clear($("VsMsg"));
        $("VsMsg").update( Vs.data.turns[Vs.turn].log);
    },

    // stop animation
    stop : function()
    {
        if (Vs.started == false)
        return false;

        if (System.isset(Vs.crystal))
        Vs.crystal.stop();

        // hide animation
        Vs.unfocus();
        $("VsAnimation").hide();
        $("VsController").hide();

        // show full log
        System.clear($("VsMsg"));

        // show gain
        $("VsGain").update(Vs.data.gain);
        // show winner
        $("VsWinner").update(Vs.data.winner);
        // show redirect
        $("VsRedirect").show();

        Dialog.hide();

        
        if (System.isset(Vs.data.info))
        {
            Vs.data.info.each(function(element)
            {
                $("VsGain").insert(element);
            });

        }

        // show combat log or not
        if (Vs.data.config.log == 0)
        {
            // clone redirect if the page is too long because of log
            $("VsMsg").insert('<div class="section_text">' + $("VsRedirect").innerHTML + '</div>');

            Vs.data.turns.each(function(element, index)
                {
                    $("VsMsg").insert('<div class="index">' + (index + 1) + '</div>');
                    $("VsMsg").insert('<div class="turn">' + element.log + '</div>');
                });
        }

        if (System.isset(Vs.data.damagemeter) == true)
        {
            $("VsMsg").insert('<div class="index">*</div>');
            $("VsMsg").insert('<div class="turn">' + Vs.data.damagemeter + '</div>');
        }


        System.register(System.rules);
        $("VsMsg").setStyle({ height : "auto" });


        /*
        if (Vs.data.config.animation == 2)
        {
            var e = $("VsSelect");
            if (e)
                e.show();
        } 
        */       
    },

    // start animation
    animate : function()
    {           
        $("VsAnimation").show();
        $("VsAnimation").scrollTo();

        System.showAt($("VsController"), $("VsAnimation"), { x : -90, y : 160 });
            
        // turns start
        Vs.turn = -1;
        Vs.maxturn = Vs.data.turns.length;

        // start crystal
        Vs.beat();

    },

    // crystal beating once per second
    beat : function()
    {
        // shield from parallel executions
        if (Vs.crystal)
        Vs.crystal.stop();

        // start beating
        Vs.crystal = new PeriodicalExecuter(function()
            {                                                    
                Vs.counter--;
                //System.clear($("VsSpeedCounter"));
                //                $("VsSpeedCounter").update(Vs.counter);

                if (Vs.counter <= 0)
                Vs.fire();
            }, 1);

            
    },

    // fire action 
    fire : function()
    {
        // hide combo
        if (Vs.comboing)
        {
            System.hideOverlay();
            Vs.counter = Vs.delay;
            return false;
        }


        if (Vs.turn + 1 >= Vs.maxturn)
        Vs.stop();
     
        Vs.next();
        Vs.counter = Vs.delay;
        
    },
        

    next : function()
    {          
        Vs.turn++;

        if (Vs.turn < Vs.maxturn)
        Vs.update();
        else
        Vs.turn = Vs.maxturn - 1;

        $("VsSpeedCounter").update(Vs.turn + 1);
    },

    previous : function()
    {
        Vs.turn--;

        if (Vs.turn >= 0)
        Vs.update();
        else
        Vs.turn = 0;

        $("VsSpeedCounter").update(Vs.turn + 1);
    },

    combo : function(card)
    {
        $("VsComboName").update(card.name);
        System.showOverlay($("OverlayCombo"), Vs.respondCombo);
        Vs.comboing = true;
        $("VsController").hide();
    },

    respondCombo : function()
    {
        $("OverlayCombo").hide();
        Vs.comboing = false;
        $("VsController").show();
    },

    // respond to battle data
    respond : function(r)
    {
        response = r.responseText.evalJSON(true);

        System.clear($("VsMsg"));

        if (response.success)
        {
            System.status($("VsMsg"), 3);
            $("VsMsg").insert(response.msg);
            System.update(response.update);

            $$(".BV_vslist_fight").each(Element.show);

            Vs.start(response);
        }
        else
        {
            var e = $("VsStart");
            if (e)
            e.show();

            // $("VsMobList").show();

            System.status($("VsMsg"), 2);
            $("VsMsg").insert(response.msg);
            //                window.reload.delay(3); // delay 3 seconds before reloading
        }
    },

    pause : function()
    {
        //console.log("pause");
        if (Vs.crystal)
        Vs.crystal.stop();

        $$(".PT_vs_speed_auto").each(Element.hide);
        $$(".PT_vs_speed_manual").each(Element.show);
//         $("VsSpeedAuto").hide();
//         $("VsSpeedManual").show();
    },


    clear : function()
    {
        $$(".PT_vs_toclear").each(function(e) { e.update(); });
    },

    rules : 
    {

        ".BV_vs_stop" : function(element) { element.onclick = Vs.stop; },
        ".BV_vs_pause" : function(element) { element.onclick = Vs.pause; },

        ".BV_vs_play" : function(element)
        {
            element.onclick = function()
            {
                Vs.beat();
                $$(".PT_vs_speed_auto").each(Element.show);
                $$(".PT_vs_speed_manual").each(Element.hide);
//                 $("VsSpeedManual").hide();
//                 $("VsSpeedAuto").show();
            };
        },


        ".BV_vs_speeddown" : function(element)
        {
            element.onclick = function()
            {
                if (Vs.delay < 10)
                Vs.delay++;
            };
        },

        ".BV_vs_speedup" : function(element)
        {
            element.onclick = function()
            {
                if (Vs.delay > 1)
                Vs.delay--;
            };
        },


        ".BV_vs_next" : function(element)
        {
            element.onclick = function()
            {
                if (Vs.working)
                    return false;
                Vs.next();
            };
        },

        ".BV_vs_previous" : function(element)
        {
            element.onclick = function()
            {
                if (Vs.working)
                    return false;
                Vs.previous();
            };
        },



        ".BV_vs_select" : function(element)
        {
            element.onclick = function()
            {
                if (Vs.working)
                return false;

                Vs.working = true;

                var id = this.id.replace("Mob", "");
                Vs.selected = id;
                $("VsMob").value = id;

                // hide old fighter
                var old = $$(".vs .selected");
                    
                if (old.length > 0)
                {
                    new Effect.Fade(old[0],
                    { duration : 0.5,
                          afterFinish : Vs.select });
                }
                else
                Vs.select();

                return false;
            };
        },

        ".BV_vs_submit" : function(element)
        {
            element.onclick = function()
            {
                var e = $("VsMobList");
                if (e)
                e.hide();

                var f = $("VsConfig");
                if (f)
                f.hide();

                $("VsStart").hide();
                Vs.clear();
                System.loading($("VsMsg"));
                    
                var param = $("VsForm").serialize(true);
                    
                System.ajax(this.href,
                {
                    method : "post",
                        parameters : { json : Object.toJSON(param) },
                        onSuccess : Vs.respond
                        });
                return false;
            };
        }
            

    }
};


var VsList = 
{
    working : false,
    id : -1,

    respond : function(r)
    {
        response = r.responseText.evalJSON(true);

        System.clear($("VsMsg"));

        if (response.success)
        {
            System.status($("VsMsg"), 3);

             var e = $("MobFight" + VsList.id);
             if (e)
                 {
                     e.removeClassName("c2");
                     e.removeClassName("lhp");
                     e.addClassName("lhp");
                 }
       
            Vs.respond(r);
        }
        else
        {
            System.status($("VsMsg"), 2);
            $("VsMsg").insert(response.msg);

            $$(".BV_vslist_fight").each(Element.show);
        }
    },


    fight : function()
    {
        Vs.stop();
        Vs.clear();
        System.loading($("VsMsg"));

        $$(".BV_vslist_fight").each(Element.hide);

        var id = this.href.split("/").pop();
        $("VsMob").value = id;
        VsList.id = id;
                    
        var param = $("VsForm").serialize(true);
                    
        System.ajax(this.href,
        {
        method : "post",
        parameters : { json : Object.toJSON(param) },
        onSuccess : VsList.respond
        });
        
        return false;
    },

    fade : function(element)
    {
        element.removeClassName("bd1");
    },

    factory : function(data)
    {
        var t = new Template($("VsMobTemplate").value);

        return t.evaluate({ t_id : data.id,
                                t_highlight : data.played ? "lhp" : "c2",
                                t_name : data.name,
                                t_avatar : data.avatar,
                                t_rank : data.rank,
                                t_classname : data.classname,
                                t_rating : data.rating,
                                t_level : data.level,
                                t_hp : data.hp
                                });
    },

    load : function(data)
    {
        VsList.working = true;
        
        var e = $("VsMobList");
        var a = $A(data.data);

        e.update();

        if (a.length <= 0)
        {
            System.status(e, 2);
            e.insert(data.error);
        }
        else
        {
            data.data.each(function(element)
                {
                    var f = VsList.factory(element);
                    e.insert(f);
                });
        }

        $("SystemInfo").update(data.info);

        var f = $("VsFormPagination");
        if (f)
          f.update(data.pagination);


        System.selectiveRegister(System.rules, "#VsMobList", [ ".BV_system_file", ".BV_system_highlight" ]);
        System.register(VsList.rules);

        $$("#VsFormPagination .index").each(function(element)
        {
            element.onclick = VsList.changep;
        });
    },

    respondChange : function(r)
    {
        response = r.responseText.evalJSON(true);

        var e = $("VsMobList"); 

        if (response.success)
        {
            VsList.load(response.data);
        }
        else
        {
            e.update();
            System.status(e, 2);
            e.insert(response.msg);
        }
        
        VsList.working = false;
    },

    change : function()
    {
        VsList.working = true;

        Vs.stop();
        Vs.clear();
        $("VsRedirect").hide();

        var param = $("VsFormFilter").serialize(true);
        var e = $("VsMobList");
        e.update();
        System.loading(e);
                    
        System.ajax($("VsFormFilter").action,
        {
            method : "post",
                parameters : { json : Object.toJSON(param) },
                onSuccess : VsList.respondChange
                    });
        return false;
    },

    changec : function()
    {
        $("VsFormIndex").value = 1;
        VsList.change();
        return false;
    },

    changer : function()
    {
        VsList.change();
        return true; // hack to make radio button selected
    },

    changep : function()
    {
        var index = this.href.split("/").pop();
        $("VsFormIndex").value = index;
        VsList.change();
        return false;
    },

    rules :
    {
        ".BV_vslist_fight" : function(element) { element.onclick = VsList.fight; },
        ".BV_vslist_loadc" : function(element) { element.onchange = VsList.changec; },
        ".BV_vslist_loadr" : function(element) { element.onclick = VsList.changer; }
    }
 
};


System.register(Vs.rules);
System.register(VsList.rules);
