package.path = package.path .. ";./assets/scripts/?.lua"
require "luascape.animate"
require "luascape.objects"
--require "luascape.core"
require "luascape.graphics"
require "luascape.input"
--require "luascape.io"
require "luascape.logic"
require "luascape.render"
require "luascape.scene"
require "luascape.import"
--require "luascape.system"
require "luascape.math"

input.createMessageInputBindings()
input.setRelativeMouse(false)
inputManager = scape.input.InputManager.instance()


camera = Camera()
camera.parallel = true
camera.translation = Vector(0, 0, 400)
camera:lookAt(Vector(0, 0, 0), Vector(0, 1, 0))
display = Display.instance()
camera.width = display.width
camera.height = display.height
camera.nearPlane = 5.0

--scape.gui.GuiManager.setDefaultBorderColor(Color(1.0, 1.0, 1.0, 0.25))
--scape.gui.GuiManager.setDefaultFillColor(Color(1.0, 1.0, 1.0, 1.0))
--scape.gui.GuiManager.setDefaultHighlightColor(Color(0.8, 0.8, 0.8, 1.0))
--scape.gui.GuiManager.setDefaultInUseColor(Color(1.0, 1.0, 1.0, 1.0))

guiManager = scape.gui.GuiManager.instance()
guiManager.guiCamera = camera
guiManager.guiScene = Scene()

guiScene = guiManager.guiScene

-- create renderer
renderer = scape.tinyandbig.Act.currentAct().renderer --Renderer()
quadPass = renderer.passes:add(QuadRenderPass())
quadPass.enabled = false
quadPass.clearFlags = Display.CLEAR_ALL
quadPass.clearColor = Color(0.2, 0.3, 0.4)
animationShader = quadPass.quad:getOrCreateShader()

standardPass = scape.tinyandbig.renderer.LevelRenderPass()
standardPass.scene = guiManager.guiScene
standardPass.camera = guiManager.guiCamera
renderer.passes:add(standardPass)

mainWindow = nil
menuStep = 0

width = display.width
height = display.height
halfWidth = width / 2.0
halfHeight = height / 2.0
heightScale = height / 512.0

mainMenuPantsPosition = Vector(halfWidth, -halfHeight, 200)
optionsPantsPosition = Vector(halfWidth, -halfHeight - 250, 200)
mainMenuPantsRotation = Quaternion(Vector.AXIS_Y, 0)
creditsPantsRotation = Quaternion(Vector.AXIS_Y, -3.1415/2.0)
creditsRotation = Quaternion(Vector.AXIS_Y, 3.1415/2.0)


function initLevel(_renderingSystem, _rootNode, _physicsSpace)
  local menu = scape.tinyandbig.Act.currentAct()

  local light = Light()
  light.name = "light"
  light.translation = Vector(1000, 1000, 1000)
  light.attenuation = 0
  light.diffuseColor=Color(0, 0, 0, 0)
  light.ambientColor=Color(0.8, 0.8, 0.8, 1.0)
  light.specularColor=Color(0.0, 0.0, 0.0, 0.0)
  light.enabled = true
  guiScene.children:add(light)
  
  
  local importer = scape.import.GIFImporter()
  local animation = FlipBookAnimation()
  importer:importAnimationFromFile("menu_04.gif", animation)
  animation.weight = 1
  local textureState = animationShader:getOrCreateTextureState()
  textureState:setMipMapping(0, TextureUnit.MIPMAP_NONE)
  local controller = animationShader.controllers:add(FlipBookShaderController(animation))
  Pacemaker.instance().updateables:add(animationShader)
  
  
  local mainWindowModel = scape.gui.WindowModel()
  mainWindowModel.name = "BackgroundImage"
  mainWindowModel.width = width + 1 --backgroundWidth
  mainWindowModel.height = height + 1
  mainWindow = scape.gui.Window(scape.gui.WindowRectangle.NO_BORDER)
  mainWindow.windowModel = mainWindowModel
  mainWindow.translation = Vector(-halfWidth, 288, -500) --Vector(backgroundX, display.height/2, -500)
  mainWindow.visual:updateMeshIfDirty()
  graphics.applyTexture(mainWindow.visual, "menu_04.png", 0)
  
  -- PC GAMER EDITION
  local pcGamerLogoModel = scape.gui.WindowModel()
  pcGamerLogoModel.name = "BackgroundImage"
  pcGamerLogoModel.width = 256
  pcGamerLogoModel.height = 128
  local pcGamerLogo = scape.gui.Window(scape.gui.WindowRectangle.NO_BORDER)
  pcGamerLogo.windowModel = pcGamerLogoModel
  pcGamerLogo.translation = Vector(50, -400, 10)
  pcGamerLogo.visual:updateMeshIfDirty()
  graphics.applyTexture(pcGamerLogo.visual, "logo_0_384.png", 0)
  mainWindow.children:add(pcGamerLogo)
  local logoBlendState = pcGamerLogo.visual.material:getOrCreateAlphaBlendState()
  logoBlendState.enabled = true
  logoBlendState.sourceFactor = AlphaBlendState.BLEND_SRC_ALPHA
  logoBlendState.destinationFactor = AlphaBlendState.BLEND_INV_SRC_ALPHA
  

  local pantsWindowModel = scape.gui.WindowModel()
  pantsWindowModel.name = "PantsImage"
  pantsWindowModel.width = display.width + 1
  pantsWindowModel.height = display.height + 1
  mainWindowModel.children:add(pantsWindowModel)
  local pantsWindow = scape.gui.Window(scape.gui.WindowRectangle.NO_BORDER)
  pantsWindow.windowModel = pantsWindowModel
  local xform = XFormVertexFilter(Matrix.translationMatrix(-halfWidth, halfHeight, 0))
  objects.applyFilter(pantsWindow, xform)
  pantsWindow.translation = Vector(halfWidth, -halfHeight, 200) --Vector(pantsWindowModel.x, -pantsWindowModel.y, 10)
  
  local pantsBlendState = pantsWindow.visual.material:getOrCreateAlphaBlendState()
  pantsBlendState.enabled = true
  pantsBlendState.sourceFactor = AlphaBlendState.BLEND_SRC_ALPHA
  pantsBlendState.destinationFactor = AlphaBlendState.BLEND_INV_SRC_ALPHA
  local pantsMaterialState = pantsWindow.visual.material:getOrCreateMaterialState()
  pantsMaterialState.ambient = Color.WHITE
  pantsMaterialState.diffuse = Color.WHITE
  
  mainWindow.children:add(pantsWindow)
  pantsWindow.visual:updateMeshIfDirty()
  graphics.applyTexture(pantsWindow.visual, "menupants.png", 0)
  local blendState = pantsWindow.visual.material:getOrCreateAlphaBlendState()
  blendState.enabled = true


  local startButtonModel = scape.gui.WindowModel()
  startButtonModel.name = "Start"
  startButtonModel.label = ""
  startButtonModel.width = 256 --pantsWidth * 0.1708
  startButtonModel.height = 128 * heightScale--display.height * 0.1692
--  startButtonModel:setPosition(pantsWindowModel.width * 0.0875, pantsWindowModel.height * 0.3857)
  pantsWindowModel.children:add(startButtonModel)
  local startButton = scape.gui.Button(scape.gui.WindowRectangle.NO_BORDER)
  startButton.unpressedTextureName = "empty.png"
  startButton.mouseOverTextureName = "start-252-266.png"
  startButton.pressedTextureName = "start-252-266.png"
  startButton.windowModel = startButtonModel
  startButton.translation = Vector(252-halfWidth, halfHeight-266 * heightScale, 50) --Vector(startButtonModel.x, -startButtonModel.y, 10)
  pantsWindow.children:add(startButton)
  local callAction = scape.gui.GuiManager.createCallAction(Value(menu), "startHandler")
  startButton:bind(Identifier("evtbutton"), callAction)
  blendState = startButton.visual.material:getOrCreateAlphaBlendState()
  blendState.enabled = true


  local optionsButtonModel = scape.gui.WindowModel()
  optionsButtonModel.name = "Options"
  optionsButtonModel.label = ""
  optionsButtonModel.width = 256
  optionsButtonModel.height = 128 * heightScale
  pantsWindowModel.children:add(optionsButtonModel)
  local optionsButton = scape.gui.Button(scape.gui.WindowRectangle.NO_BORDER)
  optionsButton.unpressedTextureName = "empty.png"
  optionsButton.mouseOverTextureName = "options-508-266.png"
  optionsButton.pressedTextureName = "options-508-266.png"
  optionsButton.windowModel = optionsButtonModel
  optionsButton.translation = Vector(508-halfWidth, halfHeight-266 * heightScale, 20)
  pantsWindow.children:add(optionsButton)
  local callAction = scape.gui.GuiManager.createCallAction(Value(menu), "optionsHandler")
  optionsButton:bind(Identifier("evtbutton"), callAction)
  blendState = optionsButton.visual.material:getOrCreateAlphaBlendState()
  blendState.enabled = true
  

  local creditsButtonModel = scape.gui.WindowModel()
  creditsButtonModel.name = "Credits"
  creditsButtonModel.label = ""
  creditsButtonModel.width = 128
  creditsButtonModel.height = 64 * heightScale
  pantsWindowModel.children:add(creditsButtonModel)
  local creditsButton = scape.gui.Button(scape.gui.WindowRectangle.NO_BORDER)
  creditsButton.unpressedTextureName = "empty.png"
  creditsButton.mouseOverTextureName = "credits-322-402.png"
  creditsButton.pressedTextureName = "credits-322-402.png"
  creditsButton.windowModel = creditsButtonModel
  creditsButton.translation = Vector(322-halfWidth, halfHeight-402 * heightScale, 70)
  pantsWindow.children:add(creditsButton)
  local callAction = scape.gui.GuiManager.createCallAction(Value(menu), "creditsHandler")
  creditsButton:bind(Identifier("evtbutton"), callAction)
  blendState = creditsButton.visual.material:getOrCreateAlphaBlendState()
  blendState.enabled = true
  

  local quitButtonModel = scape.gui.WindowModel()
  quitButtonModel.name = "Quit"
  quitButtonModel.label = ""
  quitButtonModel.width = 128
  quitButtonModel.height = 64 * heightScale
  pantsWindowModel.children:add(quitButtonModel)
  local quitButton = scape.gui.Button(scape.gui.WindowRectangle.NO_BORDER)
  quitButton.unpressedTextureName = "empty.png"
  quitButton.mouseOverTextureName = "quit-449-402.png"
  quitButton.pressedTextureName = "quit-449-402.png"
  quitButton.windowModel = quitButtonModel
  quitButton.translation = Vector(449-halfWidth, halfHeight-402 * heightScale, 50)
  pantsWindow.children:add(quitButton)
  local callAction = scape.gui.GuiManager.createCallAction(Value(menu), "quitHandler")
  quitButton:bind(Identifier("evtbutton"), callAction)
  blendState = quitButton.visual.material:getOrCreateAlphaBlendState()
  blendState.enabled = true
  
  
  -- cursor
  local cursorNode = Node()
  cursorNode:hide(true, true)
  cursorNode.visual = Grid(32, 32, 2, 2)
  local xform = XFormVertexFilter(Matrix.translationMatrix(16, -16, 0))
  objects.applyFilter(cursorNode, xform)
  local cursorBlendState = cursorNode.visual.material:getOrCreateAlphaBlendState()
  cursorBlendState.enabled = true
  cursorBlendState.sourceFactor = AlphaBlendState.BLEND_SRC_ALPHA
  cursorBlendState.destinationFactor = AlphaBlendState.BLEND_INV_SRC_ALPHA
  local cursorMaterialState = cursorNode.visual.material:getOrCreateMaterialState()
  cursorMaterialState.ambient = Color.WHITE
  cursorMaterialState.diffuse = Color.WHITE
  graphics.applyTexture(cursorNode.visual, "mauszeiger_32x32.png", 0)
  guiScene.children:add(cursorNode)
  guiManager.cursor = cursorNode
  

  menu.background = mainWindow
  menu.mainMenu = pantsWindow
  mainWindow:hide(true, true)
  guiScene.children:add(mainWindow)
end

function updateLevel()
  local menu = scape.tinyandbig.Act.currentAct()
  
  local currentIterationTime = Pacemaker.instance().frameTime
  local deltaTime = Pacemaker.instance().deltaTime
  
  -- Logo
  if (menuStep == 0) then
    standardPass.enabled = true
    guiManager.active = true
    guiScene.children:add(menu.logoMenu)
    menu.logoMenu:hide(false, true)
    menuStep = menuStep + 1
  end
  
  -- Intro text
  if (menuStep == 1 and currentIterationTime > 2.0) then
    menu.logoMenu:hide(true, true)
    guiScene.children:remove(menu.logoMenu)
    
    menu.introMenu:hide(false, true)
    guiScene.children:add(menu.introMenu)
    menuStep = menuStep + 1
  end
  
  -- Menu animation
  if (menuStep == 2 and currentIterationTime > 6.0) then
    -- Workaround for scheduled gif animation
    Pacemaker.instance().updateTimeOffset = -currentIterationTime
    currentIterationTime = 0
    menu.introMenu:hide(true, true)
    standardPass.enabled = false
    quadPass.enabled = true
    menuStep = menuStep + 1
  end
  
  -- Menu ready
  if (menuStep == 3 and currentIterationTime > 1.6) then
    standardPass.enabled = true
    quadPass.enabled = false
    Pacemaker.instance().updateables:remove(animationShader)
    animationShader = nil
    renderer.passes:remove(quadPass)
    quadPass = nil
    
    menu.background:hide(false, true)
    menu.mainMenu:hide(false, true)
    
    guiManager.cursor:hide(false, true)
    
    menuStep = menuStep + 1
  end
  
  -- animation from main menu to options
  if menu.animateToOptions then
    local translation = menu.mainMenu.translation
    menu.mainMenu.translation = translation + (optionsPantsPosition - translation) * deltaTime * 5
    local distance = optionsPantsPosition - menu.mainMenu.translation
    if distance:length() < 0.1  then
      menu.animateToOptions = false
      menu.background.children:add(menu.optionsMenu)
      menu.optionsMenu:hide(false, true)
    end
  end
  
  -- animation from options to main menu
  if menu.animateFromOptionsToMenu then
    local translation = menu.mainMenu.translation
    menu.mainMenu.translation = translation + (mainMenuPantsPosition - translation) * deltaTime * 5
    local distance = mainMenuPantsPosition - menu.mainMenu.translation
    if distance:length() < 0.1  then
      menu.mainMenu.translation = mainMenuPantsPosition
      menu.animateFromOptionsToMenu = false
      for i, child in pairs(menu.mainMenu.children) do
        child:hide(false, true)
      end
    end
  end
  
  -- animation from main menu to credits
  if menu.animateToCredits then
    if not menu.mainMenu.hidden then
      local diffAngle = (-Vector.AXIS_Z):angle(menu.mainMenu.matrix:rightVector())
      if diffAngle > 0.01  then
        menu.mainMenu.rotation = menu.mainMenu.rotation:slerp(creditsPantsRotation, deltaTime * 10, 0)
      else
        menu.mainMenu:hide(true, true)
        menu.background.children:add(menu.creditsMenu)
        menu.creditsMenu:hide(false, true)
        menu.creditsMenu.rotation = creditsRotation
      end
    else
      local diffAngle = Vector.AXIS_X:angle(menu.creditsMenu.matrix:rightVector())
      if diffAngle > 0.01  then
        menu.creditsMenu.rotation = menu.creditsMenu.rotation:slerp(mainMenuPantsRotation, deltaTime * 5, 0)
      else
        menu.mainMenu.rotation = creditsRotation
        menu.animateToCredits = false
      end
    end
  end
  
  -- animation from credits to main menu
  if menu.animateFromCreditsToMenu then
    if not menu.creditsMenu.hidden then
      local diffAngle = Vector.AXIS_Z:angle(menu.creditsMenu.matrix:rightVector())
      if diffAngle > 0.01  then
        menu.creditsMenu.rotation = menu.creditsMenu.rotation:slerp(creditsRotation, deltaTime * 10, 0)
      else
        menu.mainMenu:hide(false, false)
        menu.creditsMenu:hide(true, true)
        menu.creditsMenu.rotation = creditsRotation
      end
    else
      local diffAngle = Vector.AXIS_X:angle(menu.mainMenu.matrix:rightVector())
      if diffAngle > 0.01  then
        menu.mainMenu.rotation = menu.mainMenu.rotation:slerp(mainMenuPantsRotation, deltaTime * 5, 0)
      else
        menu.animateFromCreditsToMenu = false
        for i, child in pairs(menu.mainMenu.children) do
          child:hide(false, true)
        end
      end
    end
  end
end
