private void initComponents() {
		addWindowListener(new WindowAdapter() {
			@Override
			public void windowClosed(WindowEvent e) {
				if (!startPressed) {
					if (script != null) {
						script.ctx.controller.stop();
					}
				}
			}
		});

		for (Summoning.Familiar familiar : familiars) {
			familiarMap.put(String.format("%s (%d)", prettyName(familiar.name()), familiar.requiredLevel()), familiar);
		}

		// General
		comboBoxHouseMode = new JComboBox(new String[]{
				"Use own altar",
				"Use friends altar",
				"Detect open houses (w31, yanille)"}
		);
		comboBoxHouseMode.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				friendName.setEnabled(comboBoxHouseMode.getSelectedIndex() == 1);
				int selected = comboBoxHouseMode.getSelectedIndex();
				if (selected > 1) {
					lightBurners.setSelected(false);
				}
				ignoredPlayers.setEnabled(selected == 2);
			}
		});

		friendName = new JTextField("friend1,friend2");
		friendName.setEnabled(false);
		ignoredPlayers = new JTextField("name1, name2");
		ignoredPlayers.setEnabled(false);
		lightBurners = new JCheckBox("Light incense burners (2 clean marrentil per trip, won't offer bones unless 2 burners are lit)", true);

		comboBoxOffering = new JComboBox(Offering.values());

		// House
		disabledHouse = new JList(houseDisabledModel);
		enabledHouse = new JList(houseEnabledModel);
		addHouse = new JButton(">");
		addHouse.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				add(disabledHouse, houseDisabledModel, houseEnabledModel);
			}
		});
		removeHouse = new JButton("<");
		removeHouse.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				remove(enabledHouse, houseDisabledModel, houseEnabledModel);
			}
		});

		// Banking
		disabledBank = new JList(bankDisabledModel);
		enabledBank = new JList(bankEnabledModel);
		addBank = new JButton(">");
		addBank.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				add(disabledBank, bankDisabledModel, bankEnabledModel);
			}
		});
		removeBank = new JButton("<");
		removeBank.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				remove(enabledBank, bankDisabledModel, bankEnabledModel);
			}
		});
		disabledBank.setCellRenderer(new ListRenderer());
		enabledBank.setCellRenderer(new ListRenderer());

		// Summoning
		enableSummoning = new JCheckBox("Enable summoning");
		enableSummoning.addItemListener(new ItemListener() {
			@Override
			public void itemStateChanged(ItemEvent e) {
				final boolean enable = e.getStateChange() == ItemEvent.SELECTED;
				houseRechargeCheckbox.setEnabled(enable);
				summoningPotionCheckbox.setEnabled(enable);
				comboBoxBOB.setEnabled(enable);
			}
		});
		houseRechargeCheckbox = new JCheckBox("Only recharge summoning points at house obelisk");
		houseRechargeCheckbox.addItemListener(new ItemListener() {
			@Override
			public void itemStateChanged(ItemEvent e) {
				if (e.getStateChange() == ItemEvent.SELECTED) {
					summoningPotionCheckbox.setSelected(false);
				}
			}
		});
		summoningPotionCheckbox = new JCheckBox("Only recharge summoning points using summoning potions (inc. flasks)");
		summoningPotionCheckbox.addItemListener(new ItemListener() {
			@Override
			public void itemStateChanged(ItemEvent e) {
				if (e.getStateChange() == ItemEvent.SELECTED) {
					houseRechargeCheckbox.setSelected(false);
				}
			}
		});
		comboBoxBOB = new JComboBox(familiarMap.keySet().toArray(new String[familiarMap.size()]));

		houseRechargeCheckbox.setEnabled(false);
		summoningPotionCheckbox.setEnabled(false);
		comboBoxBOB.setEnabled(false);

		/*
		screenshotCheckbox = new JCheckBox("Save screenshot when script stops");
		screenshotFolderButton = new JButton("Open Folder");
		screenshotFolderButton.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				try {
					Desktop.getDesktop().open(Environment.getStorageDirectory());
				} catch (IOException ignored) {
				}
			}
		});
		*/
		stopOfferingCheckbox = new JCheckBox("Stop offering bones if burners go out", true);
/*
		comboBoxAura = new JComboBox<>(new MyAuras.Aura[]{
				MyAuras.Aura.CORRUPTION,
				MyAuras.Aura.HARMONY,
				MyAuras.Aura.SALVATION,
				MyAuras.Aura.GREATER_CORRUPTION,
				MyAuras.Aura.GREATER_HARMONY,
				MyAuras.Aura.GREATER_SALVATION,
				MyAuras.Aura.MASTER_CORRUPTION,
				MyAuras.Aura.MASTER_HARMONY,
				MyAuras.Aura.MASTER_SALVATION,
				MyAuras.Aura.SUPREME_CORRUPTION,
				MyAuras.Aura.SUPREME_HARMONY,
				MyAuras.Aura.SUPREME_SALVATION
		});
*/
		//enableAura = new JCheckBox("Enable Aura");

		stopLevelCheckbox = new JCheckBox("Stop at level", false);
		stopLevelCheckbox.addItemListener(new ItemListener() {
			@Override
			public void itemStateChanged(ItemEvent e) {
				stopLevelSpinner.setEnabled(e.getStateChange() == ItemEvent.SELECTED);
			}
		});

		stopLevelSpinner = new JSpinner(new SpinnerNumberModel(/*Math.min(Math.max(1, Skills.getLevel(Skills.PRAYER)) + 1, 99)*/99, 1, 99, 1));
		stopLevelSpinner.setEnabled(false);

		// Bottom
		startButton = new JButton("Start Script");
		startButton.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				startButtonActionPerformed();
			}
		});
		loadButton = new JButton("Load Settings");
		loadButton.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				loadActionPerformed();
			}
		});
		saveButton = new JButton("Save Settings");
		saveButton.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				saveActionPerformed();
			}
		});

		tabbedPane = new JTabbedPane();
		generalTab = getGeneralTab();
		houseTab = getHouseTab();
		bankTab = getBankingTab();
	}