/**
   * Removes the specified module from the registry AND the simulation bus.
   *
   * @param index Index of the module to be removed.
   * @param sim Simulation core that is being run.
   */
  public int removeModule(int index) {
    if (index >= modules.size() || index < 0) {
      return Msg.E("removeModule: invalid index:" + index, Constants.PLP_GENERIC_ERROR, null);
    }

    plp.sim.bus.remove(positionInBus.get(index));
    positionInBus.remove(index);

    if (modules.get(index).threaded && modules.get(index).isAlive()) {
      modules.get(index).stop = true;
    }

    modules.get(index).remove();
    modules.remove(index);
    regSize.remove(index);
    type.remove(index);

    if (moduleFrames.get(index) != null && moduleFrames.get(index) instanceof JFrame)
      ((JFrame) moduleFrames.get(index)).dispose();

    moduleFrames.remove(index);

    // we have to update bus positions
    for (int i = index; i < positionInBus.size(); i++) {
      Integer val = positionInBus.get(i);
      positionInBus.set(i, val - 1);
    }

    return Constants.PLP_OK;
  }
  public long getStartAddr(int index) {
    if (index >= modules.size() || index < 0) {
      Msg.E("getStartAddr: invalid index:" + index, Constants.PLP_GENERIC_ERROR, null);
      return -1;
    }

    return modules.get(index).startAddr();
  }
  /**
   * @param index Index of the module.
   * @return The type of the module
   */
  public long getType(int index) {
    if (index >= modules.size() || index < 0) {
      Msg.E("getType: invalid index:" + index, Constants.PLP_GENERIC_ERROR, null);
      return -1;
    }

    return type.get(index);
  }
  /**
   * @param index Index of the module.
   * @return The register file size of the module
   */
  public Object getRegSize(int index) {
    if (index >= modules.size() || index < 0) {
      Msg.E("getRegSize: invalid index:" + index, Constants.PLP_GENERIC_ERROR, null);
      return null;
    }

    return regSize.get(index);
  }
  /**
   * @param index Index of the module.
   * @return The position of the specified module in the simulation bus.
   */
  public int getPositionInBus(int index) {
    if (index >= modules.size() || index < 0) {
      Msg.E("getPositionInBus: invalid index: " + index, Constants.PLP_GENERIC_ERROR, null);
      return -1;
    }

    return positionInBus.get(index);
  }
  /**
   * @param index Index of the module to be retrieved.
   * @return The module at index attached to this registry.
   */
  public PLPSimBusModule getModule(int index) {
    if (index >= modules.size() || index < 0) {
      Msg.E("getModule: invalid index:" + index, Constants.PLP_GENERIC_ERROR, null);
      return null;
    }

    return modules.get(index);
  }
  /**
   * Loads a preset
   *
   * @param preset preset object to load
   */
  public int loadPreset(Preset preset) {
    Msg.D("loading preset, # of mods: " + preset.size(), 3, this);

    for (int i = 0; i < preset.size(); i++) {
      if (plp.g()) {
        this.attachModuleToBus(preset.getType(i), preset.getAddress(i), preset.getSize(i));
        if (preset.getHasFrame(i)) ((JFrame) moduleFrames.get(i)).setVisible(preset.getVisible(i));
      } else this.attachModuleToBus(preset.getType(i), preset.getAddress(i), preset.getSize(i));
    }

    return Constants.PLP_OK;
  }
  public ProgrammerDialog(ProjectDriver plp, java.awt.Frame parent, boolean modal) {
    super(parent, modal);
    initComponents();

    this.plp = plp;

    plptool.PLPToolbox.attachHideOnEscapeListener(this);

    cmbPort.removeAllItems();
    if (plp.isSerialSupported() && Config.prgAutoDetectPorts) {
      Enumeration portList = CommPortIdentifier.getPortIdentifiers();
      while (portList.hasMoreElements()) {
        CommPortIdentifier portId = (CommPortIdentifier) portList.nextElement();
        Msg.D("rxtx portId name: " + portId.getName() + " type: " + portId.getPortType(), 2, null);
        if (portId.getPortType() == CommPortIdentifier.PORT_SERIAL) {
          cmbPort.addItem(portId.getName());
        }
      }
    } else {
      if (PLPToolbox.getOS(false) == Constants.PLP_OS_LINUX_32
          || PLPToolbox.getOS(false) == Constants.PLP_OS_LINUX_64) {
        cmbPort.addItem("/dev/ttyUSB0");
        cmbPort.addItem("/dev/ttyUSB1");
        cmbPort.addItem("/dev/ttyS0");
        cmbPort.addItem("/dev/ttyS1");
      } else if (PLPToolbox.getOS(false) == Constants.PLP_OS_WIN_32
          || PLPToolbox.getOS(false) == Constants.PLP_OS_WIN_64) {
        cmbPort.addItem("COM1");
        cmbPort.addItem("COM2");
        cmbPort.addItem("COM3");
        cmbPort.addItem("COM4");
      } else cmbPort.addItem("Specify your serial port here.");
    }

    javax.swing.KeyStroke escapeKeyStroke =
        javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_ESCAPE, 0, false);
    javax.swing.Action escapeAction =
        new javax.swing.AbstractAction() {
          public void actionPerformed(java.awt.event.ActionEvent e) {
            setVisible(false);
            close();
          }
        };

    getRootPane()
        .getInputMap(javax.swing.JComponent.WHEN_IN_FOCUSED_WINDOW)
        .put(escapeKeyStroke, "ESCAPE");
    getRootPane().getActionMap().put("ESCAPE", escapeAction);

    this.setLocationRelativeTo(null);
  }
  /**
   * Loads a predefined preset
   *
   * @param index Index of the preset
   */
  public int loadPredefinedPreset(int index) {
    if (index >= Preset.presets.length || index < 0)
      return Msg.E(
          "loadPredefinedPreset: invalid index: " + index, Constants.PLP_GENERIC_ERROR, null);

    Integer[] modsType = (Integer[]) Preset.presets[index][1];
    Long[] startAddresses = (Long[]) Preset.presets[index][2];
    Long[] sizes = (Long[]) Preset.presets[index][3];
    for (int i = 0; i < modsType.length; i++) {
      if (plp.g()) this.attachModuleToBus(modsType[i], startAddresses[i], sizes[i]);
      else this.attachModuleToBus(modsType[i], startAddresses[i], sizes[i]);
    }

    return Constants.PLP_OK;
  }
  /** Creates a preset off the currently attached modules */
  public Preset createPreset() {
    Msg.D("Adding " + modules.size() + " modules to preset.", 3, this);

    Preset preset = new Preset();

    for (int i = 0; i < modules.size(); i++) {
      preset.addModuleDefinition(
          type.get(i),
          modules.get(i).startAddr(),
          regSize.get(i),
          (moduleFrames.get(i) != null && (moduleFrames.get(i) instanceof JFrame)),
          (moduleFrames.get(i) instanceof JFrame)
              ? ((JFrame) moduleFrames.get(i)).isVisible()
              : false);
    }

    return preset;
  }
  /**
   * Instantiate and attach a PLPSimBusModule-based module to this I/O registry and to the bus of
   * the given simulation core. This method also associates a module with its internal frame, if GUI
   * representation is implemented. Module developers will have to write their module's
   * initialization here.
   *
   * @param index Module type as registered in the constructor.
   * @param addr The starting address of the module's address space.
   * @param size The size of the module's address space.
   * @return PLP_OK on completion, or PLP_SIM_INVALID_MODULE if invalid index is specified.
   */
  public int attachModuleToBus(int index, long addr, long size) {
    // we're not loading dynamic modules from here (index -1)
    if (index < 0) return Constants.PLP_OK;

    PLPSimBusModule module = null;
    Object moduleFrame = null;

    Msg.D("Loading " + mods[index][0], 3, this);

    switch (index) {

        // This is where the modules are initialized when the simulator
        // requests an I/O module instance to be created.

        /** *************************************************************** */
        // PLPSimMemModule is summoned
      case 0:
        module = new MemModule(addr, size, true);

        break;

        /** *************************************************************** */
        // LEDArray is summoned
      case 1:
        module = new LEDArray(addr);
        if (plp.g()) {
          moduleFrame = new LEDArrayFrame();
          attachModuleFrameListeners((JFrame) moduleFrame, plp, Constants.PLP_TOOLFRAME_SIMLEDS);
        }

        break;

        /** *************************************************************** */
        // Switches is summoned
      case 2:
        module = new Switches(addr);
        if (plp.g()) {
          moduleFrame = new SwitchesFrame((Switches) module);
          attachModuleFrameListeners(
              (JFrame) moduleFrame, plp, Constants.PLP_TOOLFRAME_SIMSWITCHES);
        }

        break;

        /** *************************************************************** */
        // FTrace is requested, he doesn't respond to summons
      case 3:
        module = new FTracer(addr, size);
        break;

        /** *************************************************************** */
        // PLPID is summoned
      case 4:
        module = new PLPID(addr);
        if (plp.g()) {
          moduleFrame = new PLPIDFrame((PLPID) module);
          attachModuleFrameListeners((JFrame) moduleFrame, plp, Constants.PLP_TOOLFRAME_SIMPLPID);
        }
        break;

        /** *************************************************************** */
        // DummyMemory is summoned
      case 5:
        module = new DummyMemory(addr, size, true);
        break;

        /** *************************************************************** */
        // VGA is summoned
      case 6:
        if (plp.g()) {
          moduleFrame = new VGAFrame();
          attachModuleFrameListeners((JFrame) moduleFrame, plp, Constants.PLP_TOOLFRAME_SIMVGA);
        }
        module = new VGA(addr, plp.sim.bus, (VGAFrame) moduleFrame);
        module.threaded = plptool.Config.threadedModEnabled;
        module.stop = false;
        if (module.threaded) module.start();
        break;

        /** *************************************************************** */
        // Timer is summoned
      case 7:
        module = new Timer(addr, plp.sim);
        break;

        /** *************************************************************** */
        // UART is summoned
      case 8:
        if (plp.g()) {
          moduleFrame = new UARTFrame();
          attachModuleFrameListeners((JFrame) moduleFrame, plp, Constants.PLP_TOOLFRAME_SIMUART);
        }
        module = new UART(addr, (UARTFrame) moduleFrame, plp.sim);
        break;

        /** *************************************************************** */
        // Seven Segments is summoned
      case 9:
        module = new SevenSegments(addr);
        if (plp.g()) {
          moduleFrame = new SevenSegmentsFrame();
          attachModuleFrameListeners(
              (JFrame) moduleFrame, plp, Constants.PLP_TOOLFRAME_SIMSEVENSEGMENTS);
        }

        break;

        /** *************************************************************** */
        // Interrupt Controller is summoned
      case 10:
        module = new InterruptController(addr, plp.sim);

        break;

        /** *************************************************************** */
        // Bus monitor is summoned
      case 11:
        module = new BusMonitor(plp.sim);
        if (plp.g()) {
          moduleFrame = new BusMonitorFrame((BusMonitor) module, null);
        }

        break;

        /** *************************************************************** */
        // GPIO is summoned
      case 12:
        module = new GPIO(addr);
        if (plp.g()) {
          moduleFrame = new GPIOFrame((GPIO) module);
          attachModuleFrameListeners((JFrame) moduleFrame, plp, Constants.PLP_TOOLFRAME_SIMGPIO);
        }

        break;

        // ADD YOUR MODULE INITIALIZATION HERE

        // ...3rd party code...//

        /** DO NOT EDIT ANYTHING BELOW THIS * */
      default:
        return Msg.E(
            "attachModuleToBus(): invalid module ID.", Constants.PLP_SIM_INVALID_MODULE, this);
    }

    moduleFrames.add(moduleFrame);
    modules.add(module);
    type.add(index);
    regSize.add(size);
    module.enable();
    positionInBus.add(plp.sim.bus.add(module));

    // if(moduleFrame != null && moduleFrame instanceof JFrame) {
    // attachModuleFrameListeners((JFrame) moduleFrame, plp);
    // simDesktop.add((JFrame) moduleFrame);
    // ((JFrame) moduleFrame).setVisible(true);
    // }

    return Constants.PLP_OK;
  }