package ocelot.desktop.ui.widget.window

import ocelot.desktop.util.Persistable
import totoro.ocelot.brain.nbt.NBTTagCompound

trait Windowed[T <: Window] extends Persistable {
  protected def createWindow(): T

  private var _window: Option[T] = None

  final def hasWindowCreated: Boolean = _window.isDefined

  def closeWindowIfCreated(): Unit =
    if (hasWindowCreated)
      window.close()

  def closeAndDisposeWindowIfCreated(): Unit = {
    if (hasWindowCreated) {
      window.closeAndDispose()
      _window = None
    }
  }

  final def window: T = {
    if (!hasWindowCreated) {
      val window = createWindow()

      if (windowNBTTag.isDefined)
        window.load(windowNBTTag.get)

      _window = Some(window)
    }

    _window.get
  }

  // ------------------------------- NBT -------------------------------

  protected def windowNBTKey: String = "window"

  private var windowNBTTag: Option[NBTTagCompound] = None

  override def load(nbt: NBTTagCompound): Unit = {
    super.load(nbt)

    if (nbt.hasKey(windowNBTKey)) {
      windowNBTTag = Some(nbt.getCompoundTag(windowNBTKey))

      // If window was open on last save - we should
      // create it's instance & bring back to screen
      Window.State(windowNBTTag.get.getInteger("state")) match {
        case Window.State.Opening | Window.State.Open =>
          window.open()
        case _ =>
      }
    }
  }

  override def save(nbt: NBTTagCompound): Unit = {
    super.save(nbt)

    // Reusing tag if it was defined (may be useful for disposing
    // purposes in further implementations)
    if (hasWindowCreated) {
      val tag = windowNBTTag.getOrElse(new NBTTagCompound())
      window.save(tag)
      windowNBTTag = Some(tag)
    }

    // Window instance may not be created, but tag may be loaded
    if (windowNBTTag.isDefined)
      nbt.setTag(windowNBTKey, windowNBTTag.get)
  }
}