
--Checkpoint = Entity:createSubClass();
Checkpoint = Activatable:createSubClass();

function Checkpoint:init()

   Activatable.init(self);

   self:setTexture("data/bonuses.png");
   self:setGravityInfluence(0);
   self:setSpriteFrame(256, 288, 320, 384);
   self:setSize(64, 96);
   self:setBlockable(false);
   self.animFrame = 0;
   self.playerVisited = false;
   
   self.editorProperties = {
      desc = "",        -- Description in the checkpoints screen.
      levelEnd = false, -- End of level - takes the player to world map on contact.
   };

end

-- TODO: Hook this up EVERYWHERE that level switches happen. Also, put
-- it in a better place than checkpoints.
function saveAndSwitchLevel(levelName, playerClass, startEntName)

   -- Save this level (except for the player).
   saveEntities(globalData.currentLevel, "player", "worldPlayer");

   -- Load the tiles.
   loadTiles(levelName..".tiles.rle");

   -- Clear all entities.
   for i = 0, 6, 1 do
      clearLayer(i, "");
   end
   unnameDeadEntities();

   globalData.currentLevel = levelName;

   -- Load new entities.
   loadEntities(levelName);

   -- Spawn the player.
   local player = playerClass:create();
   local startEnt = entitiesByName[startEntName];
   if startEnt then
      player:setPos(startEnt:getPos());
      player:setLayer(startEnt:getLayer());
   end

   -- Save the new level, with the player.
   saveEntities(globalData.currentLevel, "");
   
   -- Save the new globalData reflecting the new level status.
   saveTable("globaldata.xml", globalData);

end

function Checkpoint:update()

   -- TODO: Different art for level start/end.

   -- Base class update.
   Activatable.update(self);

   -- Just do the simple, looping animation.
   self.animFrame = self.animFrame + 1;
   if self.animFrame > 15.9 then
	  self.animFrame = 0;
   end

   local spritex = 256 + math.floor(self.animFrame/4) * 64;
   local spritey = 288;

   -- If the player has visited this checkpoint, switch to the green
   -- flag.
   if self.playerVisited == true then
	  spritey = spritey + 96;
   end

   self:setSpriteFrame(spritex, spritey, spritex + 64, spritey + 96);

   if self.spawnCountdown then
      self.spawnCountdown = self.spawnCountdown - 1;

      if self.spawnCountdown < 0 then
         self.spawnCountdown = nil;
      end
   end


   -- Actual level transition logic...
   if fade_alphaBlack >= 1 and fade_fadeBlack and self.backToWorld then

      local worldNode = globalData.worldNodeName;
      local worldMap  = globalData.worldMapLevel;

      writeConsole("Returning to world map: "..worldNode.." in "..worldMap.."\n");

      -- In case something goes wrong, don't keep trying to do this...
      self.backToWorld = false;
      self.spawnCountdown = 10;
      fade_fadeBlack = false;

      saveAndSwitchLevel(worldMap, WorldMapPlayer, worldNode);

      if self.editorProperties then

         if self.editorProperties.levelEnd then

            -- Mark this level as done.
            local destWorldNode = entitiesByName[globalData.worldNodeName];
            if destWorldNode then

               destWorldNode.editorProperties.levelFinished = true;

               -- Save Entities again so keep that change.
               saveEntities(globalData.currentLevel, "");

            end

         end

      end

      -- This needs to happen after the new map loads, because
      -- WorldMapPlayer gets its node from it when it's created.
      globalData.worldNodeName = nil;
      globalData.worldMapLevel = nil;

   end

end

function Checkpoint:collided(otherEntName)

   -- Base class collided.
   Activatable.collided(self, otherEntName);

   -- TODO: We should save the game every time the player makes it to
   -- a checkpoint.

   -- TODO: Player should be allowed to leave the map at any
   -- checkpoint. (Or maybe this should be true for any finished map.)

   if otherEntName == "player" then

	  -- Add us and set us true in our global list of visited
	  -- checkpoints.
	  if not self.playerVisited then

		 -- Get the name of the world node this level goes with. Must
		 -- have been set by the world node.
		 local worldNodeName = globalData.worldNodeName;
		 if worldNodeName == nil then
			worldNodeName = "Unknown_Level";
		 end

		 -- Create our globalData things if they don't exist yet.
		 if not globalData.worldNodeCheckpoints then
			globalData.worldNodeCheckpoints = {};
		 end 
		 if not globalData.worldNodeCheckpoints[worldNodeName] then
			globalData.worldNodeCheckpoints[worldNodeName] = {};
		 end

         local pointDesc = self:getName();

         if self.editorProperties then
            if self.editorProperties.desc then
               if not self.editorProperties.desc == "" then
                  pointDesc = self.editorProperties.desc;
               end
            end
         end

		 -- And set the current level name there.
		 globalData.worldNodeCheckpoints[worldNodeName][self:getName()] = {
            globalData.currentLevel,
            pointDesc
         };

         -- This is actually really annoying.
         --if not (self:getName() == "Start") then
         --   popupMessageBox("Chekpoint added: "..pointDesc);
         --end

	  end

	  self.playerVisited = true;

      if not self.spawnCountdown and not (self.backToWorld) then
         
         -- Player touched it after leaving it.         
         if self.editorProperties and self.editorProperties.levelEnd then

            -- Exit the level.
            self.backToWorld = true;
            fade_fadeBlack = true;

         else

            -- TODO: Wait for activation to do this.

            -- Save the game state.
            saveEntities(globalData.currentLevel, "");
            saveTable("globaldata.xml", globalData);
            self.spawnCountdown = 10;

         end

      else

         -- Player is still sitting on the checkpoint after spawning.
         self.spawnCountdown = 10;

      end

   end

end


-- Load/Save stuff...
function Checkpoint:save()
   return {
	  playerVisited = self.playerVisited;
	  animFrame = self.animFrame;
   };
end

function Checkpoint:initFromSave(saveData)

   Activatable.init(self);

   self.playerVisited = saveData.playerVisited;
   self.animFrame = saveData.animFrame;
   
   -- If the player spawns on top of us, then give some time to get
   -- off the spawn point.
   self.spawnCountdown = 10;

end

function startGoingBackToWorldFromCheckpoint(checkpointName)
   popAndDeleteUIScreen();

   local ent = entitiesByName[checkpointName];
   if ent then
      ent.backToWorld = true;
      fade_fadeBlack = true;
   end

end

function popupReturnToWorld(checkpointName)

	local alignedBox = WidgetAlignedBox:new();
	
	local paddedBox = WidgetPaddedBox:new();
	paddedBox:setBackgroundImage("editordata/np_ff2.ninepatch");
	paddedBox:setPadding(16);
	paddedBox:setMinWidth(384);

    alignedBox:setChild(paddedBox);

    local mainContainer = WidgetContainer:new();
    paddedBox:setChild(mainContainer);
    mainContainer:setNumRows(2);
    mainContainer:setStretchableRow(1);
    
    local infoText = WidgetText:new();
    mainContainer:addChild(infoText);
    infoText:setText("Return to world map?");
    infoText:setFontName("games/lily/fonts/arcadeFont.tga");

    local selectionContainer = WidgetContainer:new();
    mainContainer:addChild(selectionContainer);

    selectionContainer:setNumRows(1);
    selectionContainer:setNumCols(3);
    selectionContainer:setStretchableCol(1);

    local buttonOk = WidgetButton:new();
    buttonOk:setLabel("Yes");
    buttonOk:setMinWidth(128);
    setButtonDefaults(buttonOk);
    buttonOk:setLuaEventHandler("onClick", "startGoingBackToWorldFromCheckpoint(\""..checkpointName.."\"); return false;");

    local buttonCancel = WidgetButton:new();
    buttonCancel:setLabel("No");
    buttonCancel:setMinWidth(128);
    setButtonDefaults(buttonCancel);
    buttonCancel:setLuaEventHandler("onClick", "popAndDeleteUIScreen(); return false;");

    selectionContainer:addChild(buttonOk);
    selectionContainer:addChild(nil);
    selectionContainer:addChild(buttonCancel);

    pushUIScreen(alignedBox);
end

function Checkpoint:activated()

   writeConsole("TODO: Checkpoint menu.\n");

   popupReturnToWorld(self:getName());

end


registerSpawn("Checkpoint");




