package ocelot.desktop.inventory.item

import ocelot.desktop.graphics.IconSource
import ocelot.desktop.inventory.traits.{CardItem, ComponentItem, PersistableItem}
import ocelot.desktop.inventory.{Item, ItemFactory, ItemRecoverer}
import ocelot.desktop.ui.widget.card.{Redstone1Window, Redstone2Window}
import ocelot.desktop.ui.widget.contextmenu.{ContextMenu, ContextMenuEntry}
import ocelot.desktop.ui.widget.tooltip.ItemTooltip
import ocelot.desktop.ui.widget.window.Windowed
import totoro.ocelot.brain.entity.Redstone
import totoro.ocelot.brain.entity.traits.{Entity, Environment}
import totoro.ocelot.brain.nbt.NBTTagCompound
import totoro.ocelot.brain.util.Tier
import totoro.ocelot.brain.util.Tier.Tier

abstract class RedstoneCardItem extends Item with ComponentItem with PersistableItem with CardItem

object RedstoneCardItem {
  abstract class Factory extends ItemFactory {
    override def name: String = s"Redstone Card (${tier.get.label})"

    override def icon: IconSource = IconSource.Items.RedstoneCard(tier.get)
  }

  class Tier1(val redstoneCard: Redstone.Tier1) extends RedstoneCardItem {
    override def entity: Entity with Environment = redstoneCard

    override def factory: Factory = RedstoneCardItem.Tier1.Factory

    override def fillTooltip(tooltip: ItemTooltip): Unit = {
      super.fillTooltip(tooltip)

      if (redstoneCard.wakeThreshold > 0)
        tooltip.addLine(s"Wake threshold: ${redstoneCard.wakeThreshold}")
    }

    // ----------------------------- Window -----------------------------

    private val windowed = new Windowed[Redstone1Window] {
      override protected def createWindow(): Redstone1Window = new Redstone1Window(redstoneCard)

      override def windowNBTKey: String = "tier1Window"
    }

    override def fillRmbMenu(menu: ContextMenu): Unit = {
      menu.addEntry(ContextMenuEntry("Redstone I/O", IconSource.Icons.ArrowRight) {
        windowed.window.open()
      })

      menu.addSeparator()

      super.fillRmbMenu(menu)
    }

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

      windowed.load(nbt)
    }

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

      windowed.save(nbt)
    }

    override def dispose(): Unit = {
      windowed.closeAndDisposeWindow()

      super.dispose()
    }
  }

  object Tier1 {
    object Factory extends Factory {
      override type I = RedstoneCardItem.Tier1

      override def itemClass: Class[I] = classOf

      override def tier: Option[Tier] = Some(Tier.One)

      override def build(): RedstoneCardItem.Tier1 = new RedstoneCardItem.Tier1(new Redstone.Tier1)

      override def recoverers: Iterable[ItemRecoverer[_, _]] = Some(ItemRecoverer(new RedstoneCardItem.Tier1(_)))
    }
  }

  class Tier2(override val redstoneCard: Redstone.Tier2) extends RedstoneCardItem.Tier1(redstoneCard) {
    override def entity: Entity with Environment = redstoneCard

    override def factory: Factory = RedstoneCardItem.Tier2.Factory

    // ----------------------------- Window -----------------------------

    private val windowed = new Windowed[Redstone2Window] {
      override protected def createWindow(): Redstone2Window = new Redstone2Window(redstoneCard)

      override def windowNBTKey: String = "tier2Window"
    }

    override def fillRmbMenu(menu: ContextMenu): Unit = {
      menu.addEntry(ContextMenuEntry("Bundled I/O", IconSource.Icons.LinesHorizontal) {
        windowed.window.open()
      })

      super.fillRmbMenu(menu)
    }

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

      windowed.load(nbt)
    }

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

      windowed.save(nbt)
    }

    override def dispose(): Unit = {
      windowed.closeAndDisposeWindow()

      super.dispose()
    }
  }

  object Tier2 {
    object Factory extends Factory {
      override type I = RedstoneCardItem.Tier2

      override def itemClass: Class[I] = classOf

      override def tier: Option[Tier] = Some(Tier.Two)

      override def build(): RedstoneCardItem.Tier2 = new RedstoneCardItem.Tier2(new Redstone.Tier2)

      override def recoverers: Iterable[ItemRecoverer[_, _]] = Some(ItemRecoverer(new RedstoneCardItem.Tier2(_)))
    }
  }
}
