/*
REWRITTEN BY XINEF
*/

#include "ScriptMgr.h"
#include "InstanceScript.h"
#include "zulfarrak.h"
#include "Player.h"
#include "TemporarySummon.h"

class instance_zulfarrak : public InstanceMapScript
{
    public:
        instance_zulfarrak() : InstanceMapScript("instance_zulfarrak", 209) { }

        InstanceScript* GetInstanceScript(InstanceMap* map) const
        {
            return new instance_zulfarrak_InstanceMapScript(map);
        }

        struct instance_zulfarrak_InstanceMapScript : public InstanceScript
        {
            instance_zulfarrak_InstanceMapScript(Map* map) : InstanceScript(map) { }

            void Initialize()
            {
                _pyramidEventProgress = NOT_STARTED;
                _gahzrillaSummoned = NOT_STARTED;
            }

            void OnGameObjectCreate(GameObject* gameobject)
            {
                if (gameobject->GetEntry() == GO_END_DOOR && _pyramidEventProgress == DONE)
                    gameobject->SetGoState(GO_STATE_ACTIVE_ALTERNATIVE);
            }

            uint32 GetData(uint32 type) const
            {
                if (type == TYPE_PYRAMID_EVENT)
                    return _pyramidEventProgress;
                return 0;
            }

            void SetData(uint32 type, uint32 data)
            {
                switch (type)
                {
                    case TYPE_PYRAMID_EVENT:
                        _pyramidEventProgress = data;
                        break;
                    case TYPE_GAHZRILLA:
                        _gahzrillaSummoned = data;
                        break;
                }

                SaveToDB();
            }

            std::string GetSaveData()
            {
                std::ostringstream saveStream;
                saveStream << "Z F " << _pyramidEventProgress << ' ' << _gahzrillaSummoned;
                return saveStream.str();
            }

            void Load(const char* str)
            {
                if (!str)
                    return;

                char dataHead1, dataHead2;
                std::istringstream loadStream(str);
                loadStream >> dataHead1 >> dataHead2;

                if (dataHead1 == 'Z' && dataHead2 == 'F')
                {
                    loadStream >> _pyramidEventProgress;
                    loadStream >> _gahzrillaSummoned;
                }
            }

        private:
            uint32 _pyramidEventProgress;
            uint32 _gahzrillaSummoned;
        };
};

class spell_zulfarrak_summon_zulfarrak_zombies : public SpellScriptLoader
{
    public:
        spell_zulfarrak_summon_zulfarrak_zombies() : SpellScriptLoader("spell_zulfarrak_summon_zulfarrak_zombies") { }

        class spell_zulfarrak_summon_zulfarrak_zombies_SpellScript : public SpellScript
        {
            PrepareSpellScript(spell_zulfarrak_summon_zulfarrak_zombies_SpellScript);

            void HandleSummon(SpellEffIndex effIndex)
            {
                if (effIndex == EFFECT_0)
                {
                    if (roll_chance_i(30))
                    {
                        PreventHitDefaultEffect(effIndex);
                        return;
                    }
                }
                else if (roll_chance_i(40))
                {
                    PreventHitDefaultEffect(effIndex);
                    return;
                }
            }

            void Register()
            {
                OnEffectHit += SpellEffectFn(spell_zulfarrak_summon_zulfarrak_zombies_SpellScript::HandleSummon, EFFECT_0, SPELL_EFFECT_SUMMON);
                OnEffectHit += SpellEffectFn(spell_zulfarrak_summon_zulfarrak_zombies_SpellScript::HandleSummon, EFFECT_1, SPELL_EFFECT_SUMMON);
            }
        };

        SpellScript* GetSpellScript() const
        {
            return new spell_zulfarrak_summon_zulfarrak_zombies_SpellScript;
        }
};

class spell_zulfarrak_unlocking : public SpellScriptLoader
{
    public:
        spell_zulfarrak_unlocking() : SpellScriptLoader("spell_zulfarrak_unlocking") { }

        class spell_zulfarrak_unlocking_SpellScript : public SpellScript
        {
            PrepareSpellScript(spell_zulfarrak_unlocking_SpellScript);

            void HandleOpenLock(SpellEffIndex effIndex)
            {
                GameObject* cage = GetHitGObj();
                std::list<WorldObject*> cagesList;
                Trinity::AllWorldObjectsInRange objects(GetCaster(), 15.0f);
                Trinity::WorldObjectListSearcher<Trinity::AllWorldObjectsInRange> searcher(GetCaster(), cagesList, objects);
                GetCaster()->VisitNearbyObject(15.0f, searcher);
                for (std::list<WorldObject*>::const_iterator itr = cagesList.begin(); itr != cagesList.end(); ++itr)
                {
                    if (GameObject* go = (*itr)->ToGameObject())
                        if (go->GetDisplayId() == cage->GetDisplayId())
                            go->UseDoorOrButton(0, false, GetCaster());
                }
            }

            void Register()
            {
                OnEffectHitTarget += SpellEffectFn(spell_zulfarrak_unlocking_SpellScript::HandleOpenLock, EFFECT_0, SPELL_EFFECT_OPEN_LOCK);
            }
        };

        SpellScript* GetSpellScript() const
        {
            return new spell_zulfarrak_unlocking_SpellScript();
        }
};

void AddSC_instance_zulfarrak()
{
    new instance_zulfarrak();
    new spell_zulfarrak_summon_zulfarrak_zombies();
    new spell_zulfarrak_unlocking();
}
