package ocelot.desktop.node.nodes

import ocelot.desktop.color.Color
import ocelot.desktop.graphics.{Graphics, IconSource}
import ocelot.desktop.inventory.item.SelfDestructingCardItem
import ocelot.desktop.node.Node.HighlightThickness
import ocelot.desktop.node.{ComputerAwareNode, WindowedNode}
import ocelot.desktop.ui.event.ClickEvent
import ocelot.desktop.ui.widget.contextmenu.ContextMenu
import ocelot.desktop.ui.widget.slot._
import ocelot.desktop.util.ComputerType.ComputerType
import ocelot.desktop.util.{AudibleComputerAware, ComputerType, DrawUtils, TierColor}
import ocelot.desktop.windows.ComputerWindow
import totoro.ocelot.brain.entity.Case
import totoro.ocelot.brain.entity.traits.Inventory
import totoro.ocelot.brain.util.Tier

class ComputerNode(val computerCase: Case)
  extends ComputerAwareNode(computerCase)
    with AudibleComputerAware
    with WindowedNode[ComputerWindow] {

  override val icon: IconSource = IconSource.Nodes.Computer.Default
  override def iconColor: Color = TierColor.get(computerCase.tier)

  override def rotatable: Boolean = true

  override def setupContextMenu(menu: ContextMenu, event: ClickEvent): Unit = {
    addPowerContextMenuEntries(menu)
    addTierContextMenuEntries(menu)

    menu.addSeparator()

    super.setupContextMenu(menu, event)
  }

  override protected def selfDestructingCards: IterableOnce[SelfDestructingCardItem] = {
    inventoryIterator.flatMap(_.get).collect {
      case item: SelfDestructingCardItem => item
    }
  }

  override def update(): Unit = {
    super.update()

    updateRunningSound()
  }

  override def dispose(): Unit = {
    super.dispose()

    soundComputerRunning.stop()
  }

  override def drawOverlay(g: Graphics): Unit = {
    val x = position.x + HighlightThickness
    val y = position.y + HighlightThickness

    DrawUtils.drawPowerOrError(g, x, y, computerCase.machine, IconSource.Nodes.Computer)
    DrawUtils.drawFilesystemActivity(g, x, y, computerCase.machine, IconSource.Nodes.Computer)

    super.drawOverlay(g)
  }

  // ---------------------------- ComputerAware ----------------------------

  override def computer: Case = computerCase
  override def computerType: ComputerType = ComputerType.Computer
  override def brainInventory: Inventory = computerCase.inventory.owner

  override def addSlotsBasedOnTier(): Unit = {
    computerCase.tier match {
      case Tier.One =>
        cardSlots = addSlotWidgets(new CardSlotWidget(_, Tier.One), new CardSlotWidget(_, Tier.One))
        memorySlots = addSlotWidgets(new MemorySlotWidget(_, Tier.One))
        diskSlots = addSlotWidgets(new HddSlotWidget(_, Tier.One))
        floppySlot = None
        cpuSlot = addSlotWidget(new ComputerCpuSlotWidget(_, this, Tier.One))
        // no idea why on earth the memory slots are split in two here
        memorySlots :+= addSlotWidget(new MemorySlotWidget(_, Tier.One))
        eepromSlot = addSlotWidget(new EepromSlotWidget(_))

      case Tier.Two =>
        cardSlots = addSlotWidgets(new CardSlotWidget(_, Tier.Two), new CardSlotWidget(_, Tier.One))
        memorySlots = addSlotWidgets(new MemorySlotWidget(_, Tier.Two), new MemorySlotWidget(_, Tier.Two))
        diskSlots = addSlotWidgets(new HddSlotWidget(_, Tier.Two), new HddSlotWidget(_, Tier.One))
        floppySlot = None
        cpuSlot = addSlotWidget(new ComputerCpuSlotWidget(_, this, Tier.Two))
        eepromSlot = addSlotWidget(new EepromSlotWidget(_))

      case _ =>
        cardSlots = {
          if (computerCase.tier == Tier.Three) {
            addSlotWidgets(
              new CardSlotWidget(_, Tier.Three),
              new CardSlotWidget(_, Tier.Two),
              new CardSlotWidget(_, Tier.Two),
            )
          } else {
            addSlotWidgets(
              new CardSlotWidget(_, Tier.Three),
              new CardSlotWidget(_, Tier.Three),
              new CardSlotWidget(_, Tier.Three),
            )
          }
        }

        memorySlots = addSlotWidgets(new MemorySlotWidget(_, Tier.Three), new MemorySlotWidget(_, Tier.Three))

        diskSlots = {
          if (computerCase.tier == Tier.Three) {
            addSlotWidgets(new HddSlotWidget(_, Tier.Three), new HddSlotWidget(_, Tier.Two))
          } else {
            addSlotWidgets(new HddSlotWidget(_, Tier.Three), new HddSlotWidget(_, Tier.Three))
          }
        }

        floppySlot = Some(addSlotWidget(new FloppySlotWidget(_)))
        cpuSlot = addSlotWidget(new ComputerCpuSlotWidget(_, this, Tier.Three))
        eepromSlot = addSlotWidget(new EepromSlotWidget(_))
    }
  }

  // ---------------------------- ShiftClickNode ----------------------------

  override protected def onShiftClick(event: ClickEvent): Unit = toggleIsTurnedOn()

  override protected def hoveredShiftStatusBarText: String = if (computer.machine.isRunning) "Turn off" else "Turn on"
}
