-----------------------------------------------------------------------------
-- CONSTANTS

    I3D_LIGHT_OMNI      = 1;
    I3D_LIGHT_SPOT      = 2;
    I3D_LIGHT_INFINITE  = 3;
    
    DEG2RAD             = 0.0174532925;
    PI                  = 3.1415927;
    TRUE                = 1;
    FALSE               = 0;
    
    
-----------------------------------------------------------------------------
-- CREATE AND NAME ENTITY

function CreateAndNameEntity(class, name, parent)
    local ent;
    ent = Entity.Create(class, parent);
    System.Assert(ent, "Failure creating entity"..name.."!");
    if (ent) then
        Entity.SetString(ent, "name", name);    
        end;
    return ent;        
    end      
    
    
-----------------------------------------------------------------------------

function CreateViewports()

    entViewport = Game.GetViewportEntity()

    -- setup a primary viewport    
    entViewportMain = Entity.Create("Viewport", entViewport);
    System.Assert(entViewportMain);
    if (entViewportMain) then
        Entity.SetString(entViewportMain, "name", "ViewportMain");
        -- viewport entities default to full-screen
        --Entity.SetFloat(entViewportMain,  "x",      0);
        --Entity.SetFloat(entViewportMain,  "y",      0);
        Entity.SetFloat(entViewportMain,  "width",  0);
        --Entity.SetFloat(entViewportMain,  "height", 920);
        Entity.SetVoid(entViewportMain, "entDrawRoot", Game.GetWorldEntity());
        Entity.SetBool(entViewportMain, "clear", TRUE);
        Entity.SetBool(entViewportMain, "setEarPos", TRUE);
        end;
        
    -- setup a second viewport for testing        
--    entViewport2 = Entity.Create("Viewport", entViewport);
--    System.Assert(entViewport2);
--    if (entViewport2) then
--        Entity.SetString(entViewport2, "name", "Main Viewport");
--        Entity.SetInt   (entViewport2, "x",      2);
--        Entity.SetInt   (entViewport2, "y",      2);
--        Entity.SetInt   (entViewport2, "width",  128);
--        Entity.SetInt   (entViewport2, "height", 128);
--        Entity.SetVoid  (entViewport2, "entDrawRoot", Game.GetWorldEntity());
--        Entity.SetBool  (entViewport2, "clear", TRUE);
--        end;        
        
    end;                 
    
    
-----------------------------------------------------------------------------

function SetupCarnivalWorld(file1, file2, file3)

    entWorld = Game.GetWorldEntity();
    
    entFirst     = CreateAndNameEntity("ENTNULL",   "First",     entWorld);
    entLast      = CreateAndNameEntity("ENTNULL",   "Last",      entWorld);
    entVeryLast  = CreateAndNameEntity("ENTNULL",   "VeryLast",  entWorld);
--  entTimeOfDay = CreateAndNameEntity("TimeOfDay", "TimeOfDay", entWorld);
    entParticles = CreateAndNameEntity("Particles", "Particles", entWorld);        
    
    CreateViewports();

    -- not sure if we really need an observer
    entObserver = Entity.Create("Observer2", entWorld);
    if (entObserver) then
        Entity.SetString (entObserver, "name", "Observer");
        --Entity.SetVector3(entObserver, "pos", 0.0, 2.0, 0.0);
        Entity.SetVector3(entObserver, "pos", 510.0, 80.0, 510.0);
        Entity.SetLocalPlayer(entObserver, 0);
        Entity.BindGamepad(entObserver, 0);
        Entity.Start     (entObserver);
        end;
        
    -- power grid should be created before most entities
    entPowerGrid = CreateAndNameEntity("MtPowerGrid", "PowerGrid", entWorld);
    if (entPowerGrid) then
        Entity.SetInt    (entPowerGrid, "numSlots", 200);
        Entity.Start     (entPowerGrid);
        end;       

    -- GroupSound handles the overall crowd sound        
    entGroupSound = CreateAndNameEntity("GroupSound", "GroupSound", entWorld);
    if (entGroupSound) then
        Entity.SetString(entGroupSound, "soundFile",   "Sound\\CrowdAmbience2b.wav");
        Entity.SetString(entGroupSound, "searchClass", "Rube1");
        Entity.SetFloat (entGroupSound, "volume",      1.0);
        Entity.SetFloat (entGroupSound, "recalcTime",  2.0);
        Entity.SetInt   (entGroupSound, "maxEnts",     60);
        Entity.Start    (entGroupSound);
        end;                      

    -- this is a static object to be used as the attraction placement cursor        
    entAttrCursor = CreateAndNameEntity("StaticObject", "AttrCursor", entVeryLast);
    if (entAttrCursor) then
        Entity.SetVector3(entAttrCursor, "pos", 512, 0, 512);
        Entity.SetString (entAttrCursor, "modelFile", "Models\\Dumpster.md3");
        Entity.SetBool   (entAttrCursor, "agl", TRUE);
        Entity.SetFlag   (entAttrCursor, EF_PASSABLE);
        Entity.SetFloat  (entAttrCursor, "visFactor", 3.0);
        Entity.Start     (entAttrCursor);
        end;        
        
    -- now, start all the entities we just made
    --Entity.StartPre(entWorld);        
    
    -- load the entity files
    if (file1) then
        Game.LoadEntitiesIni(file1);
        end;
    if (file2) then
        Game.LoadEntitiesIni(file2);
        end;
    if (file3) then
        Game.LoadEntitiesIni(file2);
        end;
    
    -- give the player some cash
    entGame = Entity.FindClass(Game.GetRootEntity(), "MtGame");
    System.Assert(entGame, "Couldn't find game entity!");
    if (entGame) then
--        Entity.SetInt(entGame, "cash", 2000000);
        Entity.StartNewDay(entGame);
        end;
        
    -- the GameGrid needs to auto-mark entities off the grid
    entGameGrid = Entity.FindClass(Game.GetRootEntity(), "GameGrid");
    if (entGameGrid) then
        Entity.Start(entGameGrid);
        end;        
        
    -- the camera needs to find the game grid, so do it here        
    entCameraMain = CreateAndNameEntity("CameraTycoon1", "CameraMain", entWorld);
    if (entCameraMain) then
        Entity.SetVector3 (entCameraMain, "pos", 510.0, 80.0, 510.0);
        Entity.SetFloat   (entCameraMain, "minPitch", 0.1);
        Entity.BindGamepad(entCameraMain, 0);    
        Entity.Start      (entCameraMain);
        end;
        
    -- this is the ride camera - pretty simple!
    entCameraRide = CreateAndNameEntity("CameraAttach", "CameraRide", entWorld);
    if (entCameraRide) then
        Entity.Start      (entCameraRide);
        end;        
        
    -- find important entities                   
    --entViewportMain = Entity.FindName(Game.GetRootEntity(), "ViewportMain");
    --entCameraMain   = Entity.FindName(Game.GetRootEntity(), "CameraMain");
    --System.Assert(entViewportMain);
    --System.Assert(entCameraMain);

    -- tell the main viewport to use the view from the main camera
    Entity.SetVoid(entViewportMain, "entCamera", entCameraMain);
    -- tell the main camera to use look at keyboard input
    Game.SetKeyboardEnt(entCameraMain);        
    
    -- send a game event notifying everyone that the world is loaded
    Entity.GameEventPre(Game.GetRootEntity(), GE_WORLDLOADED, 0);    
        
    end;