//////////////////////////////////////////////////////////////////////////////
//
// Asura_ServerEntity_ClockTrigger.h
//
// Copyright (c) 2004 Rebellion. All rights reserved.
//
// Created by Nick Davis.
//
//////////////////////////////////////////////////////////////////////////////

// B E G I N   F I L E   W R A P P E R ///////////////////////////////////////

#ifdef ASURA_USE_PRAGMA_ONCE
    #pragma once
#endif

#ifndef ___ASURA_SERVERENTITY_CLOCKTRIGGER_H___
#define ___ASURA_SERVERENTITY_CLOCKTRIGGER_H___ 1

// E N D   F I L E   W R A P P E R ///////////////////////////////////////////

//////////////////////////////////////////////////////////////////////////////
//
// includes
//
//////////////////////////////////////////////////////////////////////////////

// asura
#include "Core/Asura_Time_System.h"
#include "Entity/Triggers/Asura_ServerEntity_Trigger.h"
#ifdef ASURA_TOOLS
#include "Entity/Asura_Entity_Classification.h"
#endif

//////////////////////////////////////////////////////////////////////////////
//
// Asura_ServerEntity_ClockTrigger
//
//////////////////////////////////////////////////////////////////////////////

class Asura_ServerEntity_ClockTrigger : public Asura_ServerEntity_Trigger
{
    friend class Tools_Entity_ClockTrigger_Object;

    // inherited interface
public:
    Asura_ServerEntity_ClockTrigger( const bool bInitiallyActive = true );
	Asura_ServerEntity_ClockTrigger( Asura_Guid uGuid );
	Asura_ServerEntity_ClockTrigger( Asura_Guid uGuid, const char*& pcChunkBuffer );// constructor from load
    virtual ~Asura_ServerEntity_ClockTrigger() {}

	static void CreateFromChunkBuffer(Asura_Guid uGuid, const char*& pcChunkBuffer);

    virtual void Update();

#ifdef ASURA_TOOLS
	virtual bool CanBeIncludedInTemplate() const {return Classification == AsuraEntityClass_ClockTrigger;}
    virtual void ApplyChangesForTemplateInstance( class Tools_EntityTemplateInstance* pxInstance );
#endif


	#ifdef ASURA_TOOLS
	virtual bool SupportsCustomEvents() const { return true; }
	virtual int GetNumCustomEvents() const { return NUM_TRIGGER_TYPES; }
	virtual unsigned short* GetCustomEvent(int iIndex) { return &m_ausTriggerMessageBlocks[iIndex]; }
	virtual void GetCustomEventName(int iEventIndex, Asura_String& xEventName);
	#endif

protected:


    // we'll do the triggering ourselves, so stop the parent doing anything
    virtual bool IsTriggered() { return false; }
    virtual void OnTrigger()   {}
    virtual void OnUnTrigger() {}

    virtual int  GetChunkBufferSize();
    virtual void FillInChunkBuffer( char*& pcChunkBuffer );

	virtual void WriteToChunkStream( Asura_Chunk_Stream& xStream ) const;
	virtual void ReadFromChunkStream( Asura_Chunk_Stream& xStream);

protected:
	void UpdateHourRepeat();
    void SendMessagesInMessageBlock( const int iMessageBlockIndex );
    void UpdateHourHandOrientation( const unsigned char ucHour );
    void UpdateMinuteHandOrientation( const unsigned char ucMinute );

protected:
    enum TriggerType
    {
        TRIGGER_TYPE_UNSET                = 0x00000000,

        TRIGGER_ON_THE_QUARTER_HOUR       = 0x00000001,
        TRIGGER_ON_THE_HALF_HOUR          = 0x00000002,
        TRIGGER_ON_THE_THREE_QUARTER_HOUR = 0x00000004,
        TRIGGER_ON_THE_HOUR               = 0x00000008,
        TRIGGER_AT_SPECIFIED_TIME         = 0x00000010,
    };
    enum MessageTypeIndexHelper
    {
        QUARTER_HOUR_MESSAGES = 0,
        HALF_HOUR_MESSAGES,
        THREE_QUARTER_HOUR_MESSAGES,
        HOUR_MESSAGES,                  // this is for the main hour trigger
        HOUR_COUNT_MESSAGES,            // this is for the hour dongs
        SPECIFIED_TIME_MESSAGES,
        NUM_TRIGGER_TYPES
    };
    enum HourRepeatState
    {
        UNSET,
        INITIAL_PAUSE,
        MID_DONG_PAUSE,
    };

    struct ChunkData
    {
        enum { CURRENT_VERSION = 1 };

        int   m_iTriggerType;

        bool  m_bIncludeHourCount;
        float m_fRepeatDelay;
        float m_fTimeBetweenRepeats;

        int   m_iSpecifiedTimeHour;
        int   m_iSpecifiedTimeMinute;
        int   m_iSpecifiedTimeSecond;

        Asura_Guid m_uHourHandObjectGuid;
        Asura_Guid m_uMinuteHandObjectGuid;
    };
    struct ChunkData_V0
    {
        int   m_iTriggerType;

        bool  m_bIncludeHourCount;
        float m_fRepeatDelay;
        float m_fTimeBetweenRepeats;

        int   m_iSpecifiedTimeHour;
        int   m_iSpecifiedTimeMinute;
        int   m_iSpecifiedTimeSecond;
    };

    // typedefs/members
protected:
    // time fetching stuff
    float           m_fUpdateTimer;
    Asura_Time      m_xPrevTime;

    // hour repeat stuff
    HourRepeatState m_eHourRepeatState;
    unsigned char   m_ucNumHourRepeats;
    float           m_fHourRepeatTimer;

    // trigger stuff
    int             m_iTriggerType;

    // on the hour stuff
    bool            m_bIncludeHourCount;
    float           m_fRepeatDelay;
    float           m_fTimeBetweenRepeats;

    // specified time stuff
    int             m_iSpecifiedTimeHour;
    int             m_iSpecifiedTimeMinute;
    int             m_iSpecifiedTimeSecond;

    // clock hand stuff
    Asura_Guid      m_uHourHandObjectGuid;
    Asura_Guid      m_uMinuteHandObjectGuid;

    unsigned short  m_ausTriggerMessageBlocks[ NUM_TRIGGER_TYPES ];

protected:
    static float s_fUpdatePeriod;
};

//////////////////////////////////////////////////////////////////////////////
//
//
//
//////////////////////////////////////////////////////////////////////////////

#endif
