private Main() {
		super("Snake");

		/* Create game */
		Skin skin = new PlainSkin();
		GameConfiguration config = new GameConfiguration();
		game = new GameController(config, skin, MapLoader.plain((short)30));
		game.addActionListener(this);
		component = new Map.Component(game.getBuffer());

		/* Create panel */
		JPanel panel = new JPanel(new BorderLayout());
		panel.add(component, BorderLayout.CENTER);
		scoreLabel = new JLabel("Score: 0   Move: 0   Speed: 0");
		panel.add(scoreLabel, BorderLayout.SOUTH);
		scoreLabel.setHorizontalAlignment(JLabel.CENTER);

		/* Create menu bar */
		JMenuBar menubar;
		JMenu menu, submenu;
		JMenuItem mi;
		JRadioButtonMenuItem rmi;
		ButtonGroup group;

		menubar = new JMenuBar();
		setJMenuBar(menubar);

		/* Game Menu */
		menu = new JMenu("Game");
		menu.setMnemonic(KeyEvent.VK_G);
		menubar.add(menu);

		/* New Game */
		mi = new JMenuItem("New Game");
		mi.setActionCommand("NEW GAME");
		mi.addActionListener(this);
		mi.setMnemonic(KeyEvent.VK_N);
		mi.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_N,
		                                         KeyEvent.CTRL_MASK));
		menu.add(mi);

		/* High Scores */
		mi = new JMenuItem("High Scores");
		mi.setActionCommand("HIGH SCORES");
		mi.addActionListener(this);
		mi.setMnemonic(KeyEvent.VK_H);
		menu.add(mi);

		/* Pause Game */
		miPause = new JCheckBoxMenuItem("Pause Game");
		miPause.setActionCommand("PAUSE");
		miPause.addActionListener(this);
		miPause.setMnemonic(KeyEvent.VK_P);
		miPause.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_P, 0));
		miPause.setSelected(false);
		menu.add(miPause);

		/* Map Submenu */
		menu.addSeparator();
		submenu = new JMenu("Map");
		submenu.setMnemonic(KeyEvent.VK_M);
		menu.add(submenu);

		mi = new JMenuItem("Plain");
		mi.setActionCommand("MAP PLAIN");
		mi.addActionListener(this);
		mi.setMnemonic(KeyEvent.VK_P);
		submenu.add(mi);

		mi = new JMenuItem("Wall");
		mi.setActionCommand("MAP WALL");
		mi.addActionListener(this);
		mi.setMnemonic(KeyEvent.VK_W);
		submenu.add(mi);

		mi = new JMenuItem("Load map");
		mi.setActionCommand("MAP CUSTOM");
		mi.addActionListener(this);
		mi.setMnemonic(KeyEvent.VK_C);
		submenu.add(mi);

		/* Dificulty Subenu */
		submenu = new JMenu("Dificulty");
		submenu.setMnemonic(KeyEvent.VK_D);
		menu.add(submenu);
		group = new ButtonGroup();

		miPresets =
			new JRadioButtonMenuItem[GameConfiguration.configNames.length];
		for (int i = 0; i < miPresets.length; ++i) {
			String cfg = GameConfiguration.configNames[i];
			miPresets[i] = new JRadioButtonMenuItem(cfg);
			miPresets[i].setActionCommand("DIF " + i);
			miPresets[i].addActionListener(this);
			miPresets[i].setMnemonic(cfg.charAt(0));
			miPresets[i].setSelected(i == GameConfiguration.DEFAULT_CONFIG);
			group.add(miPresets[i]);
			submenu.add(miPresets[i]);
		}

		submenu.addSeparator();
		rmi = new JRadioButtonMenuItem("Custom");
		rmi.setActionCommand("DIF CUSTOM");
		rmi.addActionListener(this);
		rmi.setMnemonic(KeyEvent.VK_C);
		group.add(rmi);
		submenu.add(rmi);

		/* Quit Game */
		menu.addSeparator();
		mi = new JMenuItem("Quit Game");
		mi.setActionCommand("QUIT");
		mi.addActionListener(this);
		mi.setMnemonic(KeyEvent.VK_Q);
		mi.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_Q,
		                                         KeyEvent.CTRL_MASK));
		menu.add(mi);

		/* Apperence Menu */
		menu = new JMenu("Apperence");
		menu.setMnemonic(KeyEvent.VK_A);
		menubar.add(menu);

		/* Skin Submenu */
		submenu = new JMenu("Skin");
		submenu.setMnemonic(KeyEvent.VK_S);
		menu.add(submenu);

		mi = new JMenuItem("Plain skin");
		mi.setActionCommand("PLAIN SKIN");
		mi.addActionListener(this);
		mi.setMnemonic(KeyEvent.VK_P);
		submenu.add(mi);

		mi = new JMenuItem("Load skin");
		mi.setActionCommand("SELECT SKIN");
		mi.addActionListener(this);
		mi.setMnemonic(KeyEvent.VK_L);
		submenu.add(mi);

		/* Look and Feel Sub Menu */
		Comparator<String> comparator = new Comparator<String>() {
			public boolean equals(Object e) { return this == e; }
			public int compare(String s1, String s2) {
				String n1 = s1.substring(s1.lastIndexOf('.') + 1);
				String n2 = s2.substring(s2.lastIndexOf('.') + 1);
				int res = n1.compareTo(n2);
				return res == 0 ? s1.compareTo(s2) : res;
			}
		};
		TreeSet<String> set = new TreeSet<String>(comparator);
		UIManager.LookAndFeelInfo LAFarr[];
		LAFarr = UIManager.getInstalledLookAndFeels();
		if (LAFarr!=null) {
			for (UIManager.LookAndFeelInfo laf : LAFarr) {
				set.add(laf.getClassName());
			}
		}

		/* Add Look and Feel menu items */
		String currentLAF = UIManager.getLookAndFeel().getClass().getName();
		if (set.size()>1) {
			submenu = new JMenu("Look and Feel");
			submenu.setMnemonic(KeyEvent.VK_L);
			menu.add(submenu);
			group = new ButtonGroup();

			int chrSet = 0;
			for (String laf : set) {
				String name = laf.substring(laf.lastIndexOf('.')+1);
				name = name.substring(0, name.length()-11);
				rmi = new JRadioButtonMenuItem(name);
				name = name.toUpperCase();
				for (int i = 0; i<name.length(); ++i) {
					char ch = name.charAt(i);
					if (!Character.isUpperCase(ch)) continue;
					if ((chrSet & (1<<(ch - 'A')))!=0) continue;
					rmi.setMnemonic(ch);
					chrSet |= 1 << (ch - 'A');
					break;
				}
				group.add(rmi);
				submenu.add(rmi);
				rmi.setActionCommand("LAF " + laf);
				rmi.addActionListener(this);
				rmi.setSelected(currentLAF.equals(laf));
			}
		}


		/* Open window */
		setContentPane(panel);
		addKeyListener(this);
		addWindowListener(this);
		pack();
		setLocationRelativeTo(null);
		setVisible(true);

		/* Run */
		game.startGame(true);
	}