/*==LICENSE==*

CyanWorlds.com Engine - MMOG client, server and tools
Copyright (C) 2011  Cyan Worlds, Inc.

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 3 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.

You should have received a copy of the GNU General Public License
along with this program.  If not, see <http://www.gnu.org/licenses/>.

You can contact Cyan Worlds, Inc. by email legal@cyan.com
 or by snail mail at:
      Cyan Worlds, Inc.
      14617 N Newport Hwy
      Mead, WA   99021

*==LICENSE==*/
//////////////////////////////////////////////////////////////////////////////
//
//  plFixedKey
//
//////////////////////////////////////////////////////////////////////////////

#include "hsTypes.h"
#include "hsUtils.h"
#include "plUoid.h"
#include <string.h>

//// plKeySeed ///////////////////////////////////////////////////////////////
//  Our seed struct. Defined here so it doesn't have to be in the .h file

struct plKeySeed
{
    plFixedKeyId  feFixedKey;
    // NOTE: The following fields are broken out to make adding to the fixed key list easier.
    // However, what they really are, are just the fields of plUoid (including plLocation)
    UInt16      fType;
    const char  *fObj;
   
    hsBool Match( plKeySeed *p ) 
    {  
        if( ( fType == p->fType ) && stricmp( p->fObj, fObj ) == 0 )
        {
            return true;
        }
        return false;
    }
};

#include "plFixedKey.h"
#include "plCreatableIndex.h"
#include "../pnKeyedObject/plKey.h"
#include "../pnFactory/plCreator.h"

// Rules for SeedList:
    // 1) Must be in the Same order as enum fixedKey
    // 2) For now at least, all your fixed keys get put into the kGlobalFixedLoc room, reserved just for fixed keys
    // 2) Be sure your ClassIndex CLASS_INDEX(plSceneObject) matches the type of object you want to have the fixedKey
    // 3) Make sure the Obj is unique for this location/Type Combo... (validated at runtime)

plKeySeed SeedList[] = {
        //  Key Enum                    Type                                            Obj

    { kFirst_Fixed_KEY,                 CLASS_INDEX_SCOPED( plSceneObject ),            "kFirst_Fixed_KEY" },

    { kLOSObject_KEY,                   CLASS_INDEX_SCOPED( plLOSDispatch ),            "kLOSObject_KEY",               },
    { kTimerCallbackManager_KEY,        CLASS_INDEX_SCOPED( plTimerCallbackManager ),   "kTimerCallbackManager_KEY",    },
    { kConsoleObject_KEY,               CLASS_INDEX_SCOPED( pfConsole ),                "kConsoleObject_KEY",           },
    { kAudioSystem_KEY,                 CLASS_INDEX_SCOPED( plAudioSystem ),            "kAudioSystem_KEY",             },
    { kInput_KEY,                       CLASS_INDEX_SCOPED( plInputManager ),           "kInput_KEY",                   },
    { kClient_KEY,                      CLASS_INDEX_SCOPED( plClient ),                 "kClient_KEY",                  },
    { kNetClientMgr_KEY,                CLASS_INDEX_SCOPED( plNetClientMgr ),           "kNetClientMgr_KEY",            },
    { kListenerMod_KEY,                 CLASS_INDEX_SCOPED( plListener ),               "kListenerMod_KEY",             },
    { kTransitionMgr_KEY,               CLASS_INDEX_SCOPED( plTransitionMgr ),          "kTransitionMgr_KEY",           },
    { kLinkEffectsMgr_KEY,              CLASS_INDEX_SCOPED( plLinkEffectsMgr ),         "kLinkEffectsMgr_KEY",          },
    { kGameGUIMgr_KEY,                  CLASS_INDEX_SCOPED( pfGameGUIMgr ),             "kGameGUIMgr_KEY",              },
    { kGameGUIDynamicDlg_KEY,           CLASS_INDEX_SCOPED( plSceneNode ),              "kGameGUIDynamicDlg_KEY",       },
    { kVirtualCamera1_KEY,              CLASS_INDEX_SCOPED( plVirtualCam1 ),            "kVirtualCamera_KEY",           },
    { kDefaultCameraMod1_KEY,           CLASS_INDEX_SCOPED( plCameraModifier1 ),        "kDefaultCameraMod1_KEY",       },
    { kKIGUIGlue_KEY,                   CLASS_INDEX_SCOPED( pfKI ),                     "kKIGUIGlue_KEY",               },
    { kClothingMgr_KEY,                 CLASS_INDEX_SCOPED( plClothingMgr ),            "kClothingMgr_KEY",             },
    { kInputInterfaceMgr_KEY,           CLASS_INDEX_SCOPED( plInputInterfaceMgr ),      "kInputInterfaceMgr_KEY",       },
    { kAVIWriter_KEY,                   CLASS_INDEX_SCOPED( plAVIWriter ),              "kAVIWriter_KEY",               },
    { kResManagerHelper_KEY,            CLASS_INDEX_SCOPED( plResManagerHelper ),       "kResManagerHelper_KEY",        },
    { kAvatarMgr_KEY,                   CLASS_INDEX_SCOPED( plAvatarMgr ),              "kAvatarMgr_KEY",               },
    { kSimulationMgr_KEY,               CLASS_INDEX_SCOPED( plSimulationMgr ),          "kSimulationMgr_KEY",           },
    { kTransitionCamera_KEY,            CLASS_INDEX_SCOPED( plCameraModifier1 ),        "kTransitionCamera_KEY",        },
    { kCCRMgr_KEY,                      CLASS_INDEX_SCOPED( plCCRMgr ),                 "kCCRMgr_KEY",                  },
    { kNetClientCloneRoom_KEY,          CLASS_INDEX_SCOPED( plSceneNode ),              "kNetClientCloneRoom_KEY",      },
    { kMarkerMgr_KEY,                   CLASS_INDEX_SCOPED( pfMarkerMgr ),              "kMarkerMgr_KEY",               },
    { kAutoProfile_KEY,                 CLASS_INDEX_SCOPED( plAutoProfile ),            "kAutoProfile_KEY",             },
    { kGlobalVisMgr_KEY,                CLASS_INDEX_SCOPED( plVisMgr ),                 "kGlobalVisMgr_KEY",            },
    { kFontCache_KEY,                   CLASS_INDEX_SCOPED( plFontCache ),              "kFontCache_KEY",               },
    { kRelevanceMgr_KEY,                CLASS_INDEX_SCOPED( plRelevanceMgr ),           "kRelevanceMgr_KEY",            },
    { kJournalBookMgr_KEY,              CLASS_INDEX_SCOPED( pfJournalBook ),            "kJournalBookMgr_KEY"           },
    { kAgeLoader_KEY,                   CLASS_INDEX_SCOPED( plAgeLoader),               "kAgeLoader_KEY"                },
    { kBuiltIn3rdPersonCamera_KEY,      CLASS_INDEX_SCOPED( plCameraModifier1 ),        "kBuiltIn3rdPersonCamera_KEY",  },
    { kSecurePreloader_KEY,             CLASS_INDEX_SCOPED( pfSecurePreloader ),        "kSecurePreloader_KEY",         },
    

    { kLast_Fixed_KEY,                  CLASS_INDEX_SCOPED( plSceneObject ),            "kLast_Fixed_KEY",              }
};


//// plFixedKeyValidator /////////////////////////////////////////////////////
//  Static class that validates the fixed key list on startup, to make sure
//  you didn't mess up the array.

class plFixedKeyValidator
{
    private:
        static plFixedKeyValidator  fValidator;

        plFixedKeyValidator::plFixedKeyValidator()
        {
            // verify that each Seed is in the correct spot...via the enum...
            int i;
            for (i= kFirst_Fixed_KEY; i < kLast_Fixed_KEY; i++)
            {
                plKeySeed *p= &SeedList[i];
                hsAssert(i == p->feFixedKey, "The fixed key table in plFixedKey.h is invalid (a fixed key is misplaced). Please ensure the list follows the given restrictions.");
            }
                // check for duplicates
            for (i= kFirst_Fixed_KEY; i < kLast_Fixed_KEY; i++)
            {
                for (int c = i+1; c < kLast_Fixed_KEY; c++)
                {   
                    hsAssert(!SeedList[i].Match(&SeedList[c]), 
                            "The fixed key table in plFixedKey.h is invalid (there are duplicate fixed keys). Please ensure the list follows the given restrictions.");
                }
            }
        }
};

plFixedKeyValidator plFixedKeyValidator::fValidator;

//// The plUoid Fixed-Key Constructor ////////////////////////////////////////
//  Put here because a) it's fixedKey dependant and b) it ensures that this
//  file gets compiled.

plUoid::plUoid(plFixedKeyId fixedkey)
{
    hsAssert(fixedkey < kLast_Fixed_KEY, "Request for Fixed key is out of Range");

    fObjectName = nil;
    Invalidate();

    plKeySeed* p= &SeedList[fixedkey];

    fLocation = plLocation::kGlobalFixedLoc;
    fClassType = p->fType;
    fObjectName = hsStrcpy(p->fObj);
    fObjectID = 0;
    fCloneID = 0;
    fClonePlayerID = 0;
}