local Event = require("event")

local Element = {
  x = 0,
  y = 0,
  width = 1,
  height = 1,
  color = {
    bg = colors.black,
    fg = colors.white
  },
  render = {
    window = nil,
    parent = nil
  },
  visible = true,
  dirty = true,
  id = "",
  onClick = nil
}

local function createWindow(element)
  return window.create(element.render.parent, element:getX(), element:getY(), element:getWidth(), element:getHeight(), element:isVisible())
end


function Element:new(o)
  local obj = o or {}

  setmetatable(obj, self)
  obj.__index = self

  if obj.render and obj.render.parent then
    self:_reload()
  end

  return obj
end

function Element:draw()
  self.dirty = false
end

function Element:getX()
  return self.x
end

function Element:getY()
  return self.y
end

function Element:setPos(x, y)
  if (x ~= nil and self.x ~= x) or (y ~= nil and self.y ~= y) then
    self:setDirty()
    self.x = x or self.x
    self.y = y or self.y

    self:_reload()
  end
end

function Element:setX(x)
  if self.x ~= x then
    self:setDirty()
    self.x = x
    self:_reload()
  end
end

function Element:setY(y)
  if self.y ~= y then
    self:setDirty()
    self.y = y
    self:_reload()
  end
end

function Element:setParent(parent)
  if self.parent ~= parent then
    self:setDirty()
    self.parent = parent
  end
end

function Element:setFgColor(color)
  if color ~= self.color.fg then
    self:setDirty()
    self.color.fg = color
    self.render.window.setTextColor(color)
  end
end

function Element:setBgColor(color)
  if color ~= self.color.bg then
    self:setDirty()
    self.color.bg = color
    self.render.window.setBackgroundColor(color)
  end
end

function Element:setVisible(visible)
  self.render.window.setVisible(visible)
end

function Element:resize(opts)
  if (opts.width ~= nil and self.x ~= opts.width) or (opts.height ~= nil and self.y ~= opts.height) then
    self:setDirty()
    self.width = opts.width or self.width
    self.height = opts.height or self.height
    self:_reload()
  end
end

function Element:setWidth(width)
  if width ~= self.width then
    self:setDirty()
    self.width = width
    self:_reload()
  end
end

function Element:setHeight(height)
  if height ~= self.height then
    self:setDirty()
    self.height = height
    self:_reload()
  end
end

function Element:getWidth()
  return self.width
end

function Element:getHeight()
  return self.height
end

function Element:getPos()
  return self.x, self.y
end

function Element:isVisible()
  return self.visible
end

function Element:setDirty()
  self.dirty = true
end

function Element:findById(id)
  if self:getId() == id then
    return self
  else
    return nil
  end
end

function Element:getId()
  return self.id
end

function Element:redraw()
  self.render.window.redraw()
end

function Element:handleEvent(evt)
  if Event.isClickEvent(evt) and self.onClick ~= nil then
    local x, y, source = Event.getClickParams(evt)
    return not not self.onClick(self, x, y, source)
  end
  return false
end

function Element:setOnClick(onClick)
  self.onClick = onClick
end

function Element:_reload()
  self.render.window = createWindow(self)
end

return Element