package ocelot.desktop.node

import ocelot.desktop.entity.{Camera, OcelotBlock, OpenFMRadio}
import ocelot.desktop.graphics.IconSource
import ocelot.desktop.node.nodes._
import totoro.ocelot.brain.entity.{
  Cable, Case, ColorfulLamp, FloppyDiskDrive, HologramProjector, IronNoteBlock, Microcontroller, NoteBlock, Rack, Raid,
  Relay, Screen, TapeDrive,
}
import totoro.ocelot.brain.util.Tier

import scala.collection.mutable

object NodeRegistry {
  val groups: mutable.ArrayBuffer[NodeTypeGroup] = mutable.ArrayBuffer[NodeTypeGroup]()

  private var group: NodeTypeGroup = _

  private def nextGroup(name: String): Unit = {
    group = new NodeTypeGroup(name)
    groups += group
  }

  private def addType(nodeType: NodeType): Unit = {
    group.types += nodeType
  }

  // ------------------------------ Original nodes ------------------------------

  nextGroup("Original")

  for (tier <- Tier.One to Tier.Creative) {
    addType(NodeType(s"Computer Case (${tier.label})", IconSource.Nodes.Computer.Default, tier) {
      new ComputerNode(new Case(tier))
    })
  }

  addType(NodeType("Rack", IconSource.Nodes.Rack.Default, None) {
    new RackNode(new Rack)
  })

  for (tier <- Tier.One to Tier.Three) {
    addType(NodeType(s"Screen (${tier.label})", IconSource.Nodes.Screen.Standalone, tier) {
      val node = new ScreenNode(new Screen(tier))
      node.attachKeyboard()
      node
    })
  }

  addType(NodeType("Disk Drive", IconSource.Nodes.DiskDrive.Default, None) {
    new DiskDriveNode(new FloppyDiskDrive())
  })

  addType(NodeType("Raid", IconSource.Nodes.Raid.Default, None) {
    new RaidNode(new Raid)
  })

  for (tier <- Tier.One to Tier.Two) {
    addType(NodeType(s"Hologram Projector (${tier.label})", IconSource.Nodes.HologramProjector(tier), None) {
      new HologramProjectorNode(new HologramProjector(tier))
    })
  }

  addType(NodeType("Note Block", IconSource.Nodes.NoteBlock, None) {
    new NoteBlockNode(new NoteBlock)
  })

  addType(NodeType("Microcontroller", IconSource.Nodes.Microcontroller.Default, None) {
    new MicrocontrollerNode(new Microcontroller(Tier.Two))
  })

  addType(NodeType("Relay", IconSource.Nodes.Relay, None) {
    new RelayNode(new Relay)
  })

  addType(NodeType("Chest", IconSource.Nodes.Chest, None) {
    new ChestNode
  })

  addType(NodeType("Cable", IconSource.Nodes.Cable, None) {
    new CableNode(new Cable)
  })

  // ------------------------------ Addon nodes ------------------------------

  nextGroup("Addons")

  addType(NodeType("Iron Note Block", IconSource.Nodes.IronNoteBlock, None) {
    new IronNoteBlockNode(new IronNoteBlock)
  })

  addType(NodeType("Camera", IconSource.Nodes.Camera, None) {
    new CameraNode(new Camera)
  })

  addType(NodeType("Colorful Lamp", IconSource.Nodes.Lamp, None) {
    new ColorfulLampNode(new ColorfulLamp)
  })

  addType(NodeType("OpenFM Radio", IconSource.Nodes.OpenFMRadio, None) {
    new OpenFMRadioNode(new OpenFMRadio)
  })

  addType(NodeType("Tape Drive", IconSource.Nodes.TapeDrive, None) {
    new TapeDriveNode(new TapeDrive)
  })

  // ------------------------------ Custom nodes ------------------------------

  nextGroup("Custom")

  addType(NodeType("Ocelot Block", IconSource.Nodes.OcelotBlock.Default, None) {
    new OcelotBlockNode(new OcelotBlock)
  })
}
