//
// Copyright(C) 2014-2015 Samuel Villarreal
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program 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 General Public License for more details.
//
// DESCRIPTION:
//      Misc Portal Hub Object Classes
//

#include "scripts/common.txt"

//-----------------------------------------------------------------------------
//
// Hub Portal Panel
//
//-----------------------------------------------------------------------------

/*
==============================================================
TurokPortalPanel
==============================================================
*/

class TurokPortalPanel : TurokFloorMover
{
    int m_levelAccess;
    
    TurokPortalPanel(kActor @actor)
    {
        super(actor);
        m_levelAccess = 0;
    }
    
    /*
    ==============================================================
    OnTick
    ==============================================================
    */
    
    void OnTick(void)
    {
        if(self.TID() == 8)
        {
            if((stateFlags & TFF_MOVING) != 0)
            {
                LowerFloor();
            }
            
            if((stateFlags & TFF_WAITING) != 0)
            {
                World.ChangeAreaFlag(self.AreaID(), AAF_TELEPORT, true);
                stateFlags &= ~(TFF_MOVING|TFF_WAITING);
            }
        }
    }
    
    /*
    ==============================================================
    OnSpawn
    ==============================================================
    */
    
    void OnSpawn(void)
    {
    }
    
    /*
    ==============================================================
    OnRestore
    ==============================================================
    */
    
    void OnRestore(void)
    {
        if(self.TID() == 8)
        {
            TurokFloorMover::OnRestore();
        }
    }
    
    /*
    ==============================================================
    OnBeginLevel
    ==============================================================
    */
    
    void OnBeginLevel(void)
    {
        kRenderModel @model = self.RenderModel();
        int nPieces;
        
        if(model is null)
        {
            return;
        }
        
        model.SetVisibility(1, false);
        model.SetVisibility(2, false);
        model.SetVisibility(3, false);
        
        switch(self.TID())
        {
        case 3:
            model.SetTexture(1, 1);
            model.SetTexture(2, 1);
            model.SetTexture(3, 1);
            break;
        case 4:
            model.SetTexture(1, 2);
            model.SetTexture(2, 2);
            model.SetTexture(3, 2);
            break;
        case 5:
            model.SetTexture(1, 3);
            model.SetTexture(2, 3);
            model.SetTexture(3, 3);
            break;
        case 6:
            model.SetTexture(1, 4);
            model.SetTexture(2, 4);
            model.SetTexture(3, 4);
            break;
        case 7:
            model.SetTexture(1, 5);
            model.SetTexture(2, 5);
            model.SetTexture(3, 5);
            break;
            
        case 8:
            model.SetVisibility(4, false);
            model.SetVisibility(5, false);
            break;
        }
        
        nPieces = 0;
        GameVariables.GetInt("hubPanelPieces" + (self.TID()-1), nPieces);
        
        for(int i = 0; i < 6; ++i)
        {
            if((nPieces & (1 << i)) != 0)
            {
                m_levelAccess++;
                self.RenderModel().SetVisibility(i+1, true);
            }
            else
            {
                self.RenderModel().SetVisibility(i+1, false);
            }
        }
    }
    
    /*
    ==============================================================
    OnActivate
    ==============================================================
    */
    
    void OnActivate(void)
    {
        self.Flags() &= ~AF_ACTIVATED;
        
        //[BP_Randomizer]
        if(BPR::g_bForceLevelPortalActivate)
        {
            return;
        }
        
        switch(self.TID())
        {
        case 2:
            Game.PrintLine("$str_112", 0); // Jungle
            break;
        case 3:
            Game.PrintLine("$str_113", 0); // The Ancient City
            break;
        case 4:
            Game.PrintLine("$str_114", 0); // The Ruins
            break;
        case 5:
            Game.PrintLine("$str_115", 0); // The Catacombs
            break;
        case 6:
            Game.PrintLine("$str_116", 0); // The Treetop Village
            break;
        case 7:
            Game.PrintLine("$str_117", 0); // The Lost Land
            break;
        case 8:
            Game.PrintLine("$str_118", 0); // The Final Confrontation
            break;
        }
        
        Game.PrintLine("ACCESS TO LEVEL " + self.TID(), 1);
        CheckLock(self.TID());
    }
    
    /*
    ==============================================================
    CheckLock
    ==============================================================
    */
    
    void CheckLock(const int hub)
    {
        int nKeys, remainingKeys, keyBits;
        int oldAccess;
        
        if(!Game.GetHubKeyInfo(hub, nKeys, remainingKeys, keyBits))
        {
            return;
        }
        
        oldAccess = m_levelAccess;
        m_levelAccess = 0;
        
        // assuming 6 being the most number of keys for a level
        for(int i = 0; i < 6; ++i)
        {
            if((keyBits & (1 << i)) != 0)
            {
                m_levelAccess++;
                self.RenderModel().SetVisibility(i+1, true);
            }
            else
            {
                self.RenderModel().SetVisibility(i+1, false);
            }
        }
        
        if(oldAccess != m_levelAccess)
        {
            self.PlaySound("sounds/shaders/health_pickup_1.ksnd");
            GameVariables.SetValue("hubPanelPieces" + (hub-1), "" + keyBits);
            
            if(hub == 8 && m_levelAccess >= 5)
            {
                self.Flags()    |= AF_ACTIVATED;
                stateFlags      |= TFF_MOVING;
                lerpTime        = 0.0f;
                currentTime     = 0.0f;
                destHeight      = self.Origin().z;
                distance        = self.FloorHeight();
                
                self.MarkPersistentBit(false);
            }
        }
    }
};

//-----------------------------------------------------------------------------
//
// Hub Portal Plaque
//
//-----------------------------------------------------------------------------

/*
==============================================================
TurokPortalPlaque
==============================================================
*/

class TurokPortalPlaque : BPR::CL_BPR_WorldObject //[BP_Randomizer]
{
    kActor @self;
    
    TurokPortalPlaque(kActor @actor)
    {
		super(actor); //[BP_Randomizer]
        @self = actor;
    }
    
    /*
    ==============================================================
    OnBeginLevel
    ==============================================================
    */
    
    void OnPostBeginLevel(void)
    {
        kRenderModel @model = self.RenderModel();
        int nKeys, remainingKeys, keyBits;
        int hubID;
        
        if(model is null)
        {
            return;
        }
        
        // handle Chronosceptor pieces
        if(self.TID() >= 100)
        {
            int chronoBits = 0;
            int bitNum = self.TID() - 100;
        
            GameVariables.GetInt("chronoPieceFlags", chronoBits);
            
            // darken tile if player does not have the corresponding piece
            if((chronoBits & (1 << bitNum)) == 0)
            {
                self.RunFxEvent("PortalPlaque_Setup");
            }
            else
            {
                return;
            }
        }
        
        switch(self.TID())
        {
        case 40:
        case 41:
        case 42:
            hubID = 4;
            model.SetTexture(0, 2);
            break;
        case 50:
        case 51:
        case 52:
            hubID = 5;
            model.SetTexture(0, 3);
            break;
        case 60:
        case 61:
        case 62:
            hubID = 6;
            model.SetTexture(0, 4);
            break;
        case 70:
        case 71:
        case 72:
            hubID = 7;
            model.SetTexture(0, 5);
            break;
        case 80:
        case 81:
        case 82:
        case 83:
        case 84:
            hubID = 8;
            model.SetTexture(0, 6);
            break;
        }
        
        // darken the plaque if we don't have the key for that level
        if(Game.GetHubKeyInfo(hubID, nKeys, remainingKeys, keyBits))
        {
            int key = self.TID() % 10;
            
            if((keyBits & (1 << key)) == 0)
            {
                self.RunFxEvent("PortalPlaque_Setup");
            }
        }
    }
    
    /*
    ==============================================================
    OnTick
    ==============================================================
    */
    
    void OnTick(void)
    {
    }
    
    /*
    ==============================================================
    OnSpawn
    ==============================================================
    */
    
    void OnSpawn(void)
    {
    }
    
    /*
    ==============================================================
    OnActivate
    ==============================================================
    */
    
    void OnActivate(void)
    {
    }
};

//-----------------------------------------------------------------------------
//
// Hub Portal Gate
//
//-----------------------------------------------------------------------------

/*
==============================================================
PortalGate
==============================================================
*/

class PortalGate : BPR::CL_BPR_WorldObject //[BP_Randomizer]
{
    kActor @self;
    
    PortalGate(kActor @actor)
    {
		super(actor); //[BP_Randomizer]
        @self = actor;
    }
    
    /*
    ==============================================================
    UpdateTexture
    ==============================================================
    */
    
    void UpdateTexture(void)
    {
        kRenderModel @model = self.RenderModel();
        
        if(model is null)
        {
            return;
        }

        int tid = self.TID();
        int newTextureNum = (tid - 2);

        if(Game.GetCurrentMapID() == 5 && tid >= 2 && tid <= 7)
        {
            int nPieces = 0;
            GameVariables.GetInt("hubPanelPieces" + (tid - 1), nPieces);
            for(int i = 0; i < 3; ++i)
            {
                if((nPieces & (1 << i)) != 0)
                {
                    model.SetTexture((i+1), newTextureNum);
                }
                else
                {
                    model.SetTexture((i+1), newTextureNum + 7);
                }
            }
        }
        else
        {
            model.SetTexture(1, newTextureNum);
            model.SetTexture(2, newTextureNum);
            model.SetTexture(3, newTextureNum);
        }
    }
    
    /*
    ==============================================================
    OnBeginLevel
    ==============================================================
    */
    
    void OnBeginLevel(void)
    {
        UpdateTexture();
    }
    
    /*
    ==============================================================
    OnTick
    ==============================================================
    */
    
    void OnTick(void)
    {
        UpdateTexture();
    }
    
    /*
    ==============================================================
    OnSpawn
    ==============================================================
    */
    
    void OnSpawn(void)
    {
    }
    
    /*
    ==============================================================
    OnActivate
    ==============================================================
    */
    
    void OnActivate(void)
    {
    }
};
