-- options/widgets :: options menu widgets

--[[
  Copyright © 2019 Kazhnuz

  Permission is hereby granted, free of charge, to any person obtaining a copy of
  this software and associated documentation files (the "Software"), to deal in
  the Software without restriction, including without limitation the rights to
  use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
  the Software, and to permit persons to whom the Software is furnished to do so,
  subject to the following conditions:

  The above copyright notice and this permission notice shall be included in all
  copies or substantial portions of the Software.

  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
  FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
  COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
  IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
]]

local widgets   = {}

local Widget            = require "gamecore.modules.menusystem.widgets"
local DoubleTextWidget  = Widget.Text:extend()

widgets.SubMenu       = DoubleTextWidget:extend()
widgets.Dummy         = Widget.Text:extend()
widgets.Exit          = Widget.Text:extend()
widgets.Switch        = DoubleTextWidget:extend()
widgets.Resolution    = DoubleTextWidget:extend()
widgets.Lang          = Widget.Text:extend()
widgets.PlayerSubMenu = DoubleTextWidget:extend()
widgets.Key           = DoubleTextWidget:extend()
widgets.Audio         = DoubleTextWidget:extend()

-- BASIC WIDGETS
-- Simple and reusables widgets

-- DoubleText widget : a two-side text widget

function DoubleTextWidget:new(menu, font, label1, label2)
  DoubleTextWidget.super.new(self, menu, font, label1)
  self.label2 = label2 or ""
end

function DoubleTextWidget:drawCanvas()
  local w, h
  w = math.floor(self.width)
  h = math.floor(self.height / 2) - (self.font:getHeight() / 2)
  self.font:draw(self.label, 4, h, -1, "left")
  self.font:draw(self.label2, w-4, h, -1, "right")
end

-- Submenu widget :: go to a submenu

function widgets.SubMenu:new(scene, menu, newmenu, fullname, order, label2)
  self.scene = scene
  local widgetmenu  = self.scene.menusystem.menus[menu]
  local font        = self.scene.assets.fonts["medium"]
  local label       = core.lang:translate("options", fullname)
  local label2      = label2 or ">"
  self.newmenu      = newmenu
  widgets.SubMenu.super.new(self, widgetmenu, font, label, label2)
  self.order = order or 0
end

function widgets.SubMenu:action()
  self.scene.assets:playSFX("confirm")
  self.scene.menusystem:switchMenu(self.newmenu)
end

-- Dummy widget :: An empty widget to serve as a base for others

function widgets.Dummy:new(scene, menu, fullname)
  self.scene = scene
  local widgetmenu  = self.scene.menusystem.menus[menu]
  local font        = self.scene.assets.fonts["medium"]
  widgets.Dummy.super.new(self, widgetmenu, font, fullname)
end

function widgets.Dummy:action()
  -- shoosh
end

-- Exit Widget : exit the examples

function widgets.Exit:new(scene, menu)
  self.scene = scene
  local widgetmenu  = self.scene.menusystem.menus[menu]
  local font        = self.scene.assets.fonts["medium"]
  local label       = core.lang:translate("commons", "exit")
  widgets.Exit.super.new(self, widgetmenu, font, "Exit")
end

function widgets.Exit:action()
  self.scene.assets:playSFX("confirm")
  core.scenemanager:setStoredScene("mainmenu")
end

-- VIDEO WIDGETS
-- Handle graphical settings

-- Switch widget (One widget to handle graphical switch)

function widgets.Switch:new(scene, menu, keyname)
  self.scene = scene
  local widgetmenu  = self.scene.menusystem.menus[menu]
  local font        = self.scene.assets.fonts["medium"]
  self.keyname      = keyname
  local label       = core.lang:translate("options", keyname)
  local label2      = self:getLabel()
  widgets.Switch.super.new(self, widgetmenu, font, label, label2)
  self.order = order or 0
end

function widgets.Switch:modifyKey()
  --self.key = (self.key == false)
  if self.keyname == "fullscreen" then
    core.options.data.video.fullscreen = (core.options.data.video.fullscreen == false)
  elseif self.keyname == "borders" then
    core.options.data.video.border = (core.options.data.video.border == false)
  elseif self.keyname == "vsync" then
    core.options.data.video.vsync = (core.options.data.video.vsync == false)
  end
  core.screen:applySettings()
end

function widgets.Switch:getKey()
  if self.keyname == "fullscreen" then
    self.key = core.options.data.video.fullscreen
  elseif self.keyname == "borders" then
    self.key = (core.options.data.video.border)
  elseif self.keyname == "vsync" then
    self.key = (core.options.data.video.vsync)
  end
end

function widgets.Switch:getLabel()
  self:getKey()
  local label = ""
  if (self.key) then
    label = "true"
  else
    label = "false"
  end

  return core.lang:translate("commons", label)
end

function widgets.Switch:action()
  self:modifyKey()
  self.scene.assets:playSFX("confirm")
  self.label2 = self:getLabel()
  core.options:write()
  self:invalidateCanvas()
end

-- Resolution Widget

function widgets.Resolution:new(scene, menu)
  self.scene = scene
  local widgetmenu  = self.scene.menusystem.menus[menu]
  local font        = self.scene.assets.fonts["medium"]
  local label       = core.lang:translate("options", "resolution")
  local label2      = self:getLabel()
  widgets.Resolution.super.new(self, widgetmenu, font, label, label2)
end

function widgets.Resolution:getLabel()
  return "x" .. core.options.data.video.resolution
end

function widgets.Resolution:action()
  if core.options.data.video.resolution == 3 then
    core.options.data.video.resolution = 1
  else
    core.options.data.video.resolution = core.options.data.video.resolution + 1
  end
  self.label2 = self:getLabel()
  core.screen:applySettings()
  self.scene.assets:playSFX("confirm")
  self:invalidateCanvas()
  core.options:write()
end

-- LANGS WIDGET
-- Allow you to change the lang of the game

function widgets.Lang:new(scene, menu, lang)
  self.scene = scene
  local widgetmenu  = self.scene.menusystem.menus[menu]
  local font        = self.scene.assets.fonts["medium"]
  local label       = core.lang:getLangName(lang)
  self.lang         = lang
  widgets.Lang.super.new(self, widgetmenu, font, label)
end

function widgets.Lang:action()
  self.scene.assets:playSFX("confirm")
  core.options:setLanguage(self.lang)
  --self.scene.menusystem:invalidateAllWidgets()
end

-- INPUT WIDGETS
-- Widgets to handle inputs

function widgets.PlayerSubMenu:new(scene, menu, sourceid)
  self.scene = scene
  local widgetmenu  = self.scene.menusystem.menus[menu]
  local font        = self.scene.assets.fonts["medium"]
  local label       = core.lang:translate("options", "player") .. " " .. sourceid
  local label2      =  ">"
  self.newmenu      = "player" .. sourceid
  widgets.PlayerSubMenu.super.new(self, widgetmenu, font, label, label2)
  self.order = 0
end

function widgets.PlayerSubMenu:action()
  self.scene.assets:playSFX("confirm")
  self.scene.menusystem:switchMenu(self.newmenu)
end

-- Key widgets

function widgets.Key:new(scene, sourceid, key)
  self.scene  = scene
  self.source = sourceid
  self.key    = key

  local menu        = "player" .. self.source

  local widgetmenu  = self.scene.menusystem.menus[menu]
  local font        = self.scene.assets.fonts["medium"]
  local label       = self.key
  local label2      = self:getLabel()

  widgets.Key.super.new(self, widgetmenu, font, label, label2)
  self.order = 0
end

function widgets.Key:getLabel()
  return core.input.data[self.source].keys[self.key]
end

function widgets.Key:action()
  self.scene.assets:playSFX("navigate")
  self.scene:changeKey(self)
  self.scene.menusystem:deactivate()
end

function widgets.Key:receiveKey( key )
  self.scene.assets:playSFX("confirm")
  core.options:setInputKey(self.source, self.key, key)
  self.label2 = self:getLabel()
  self:invalidateCanvas()
end

-- AUDIO FUNCTIONS
-- Sounds/Music functions

function widgets.Audio:new(scene, menu, audiotype)
  self.scene      = scene
  self.audiotype  = key


  local widgetmenu  = self.scene.menusystem.menus[menu]
  local font        = self.scene.assets.fonts["medium"]
  self.audiotype = audiotype
  local label = ""
  if (self.audiotype == "sfx") then
    label       = core.lang:translate("options", "sfx")
  else
    label       = core.lang:translate("options", "music")
  end
  local label2  = self:getLabel()

  widgets.Audio.super.new(self, widgetmenu, font, label, label2)
  self.order = 0
end

function widgets.Audio:getLabel()
  local value = self:getVolume()
  string = utils.math.numberToString(value, 3)
  local label = string .. "%"

  return label
end

function widgets.Audio:getVolume()
  if (self.audiotype == "sfx") then
    return core.options.data.audio.sfx
  else
    return core.options.data.audio.music
  end
end

function widgets.Audio:setVolume(vol)
  if (vol < 0) then vol = 100 end

  if (self.audiotype == "sfx") then
    core.options.data.audio.sfx   = vol
  else
    core.options.data.audio.music = vol
  end

  self.label2 = self:getLabel()
  self:invalidateCanvas()
end

function widgets.Audio:action()
  local value = self:getVolume()
  self:setVolume(value - 20)
  self.scene.assets:playSFX("confirm")
  self.scene.assets.music:setVolume(core.options.data.audio.music / 100)
  core.options:write()
end

return widgets
