package com.okseby.win;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.Box;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.border.EtchedBorder;

import org.fife.rsta.ac.LanguageSupportFactory;
import org.fife.ui.autocomplete.*;
import org.fife.ui.rsyntaxtextarea.RSyntaxTextArea;
import org.fife.ui.rsyntaxtextarea.SyntaxConstants;
import org.fife.ui.rtextarea.RTextScrollPane;

import com.okseby.io.Open;
import com.okseby.io.Save;
import com.okseby.utils.Providers;

public class Window implements Runnable {
	public static RSyntaxTextArea textArea;
	public static boolean isFileOpened;
	
	JFrame window;
	JMenuBar menuBar;
	JMenu fileMenu;
	JMenu editMenu;
	JFileChooser browser;
	JButton quitButton;
	JButton saveOptionDialogButton;
	JButton discardOptionDialogButton;
	JMenuItem fileMenuOpen, fileMenuSave, fileMenuClose;
	JPanel fileExplorer;
	JPanel mainPanel;
	RTextScrollPane scrollPane;
	CompletionProvider completionProvider;
	AutoCompletion autoComplete;

	String title;
	String p;
	int status;
	double version;
	Dimension winSize;
	
	Object[] options = {null, null};

	public void setup() {
		menuBar.add(fileMenu);
		menuBar.add(editMenu);
		menuBar.add(Box.createHorizontalGlue());
		menuBar.add(quitButton);

		fileMenu.add(fileMenuOpen);
		fileMenu.add(fileMenuSave);
		fileMenu.add(fileMenuClose);

		browser.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				if (e.getActionCommand().equals(javax.swing.JFileChooser.APPROVE_SELECTION)) {
					p = browser.getSelectedFile().getPath();
					
					if (browser.getDialogType() == JFileChooser.OPEN_DIALOG) {
						Open.readFile(p);
					}
					
					isFileOpened = true;
					window.setTitle(title + " - " + browser.getSelectedFile().getName());
				}
			}
		});

		fileMenuOpen.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				status = browser.showOpenDialog(window);
			}
		});
		
		fileMenuSave.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				if (isFileOpened) {
					Save.saveFile(p);
				} else {
					status = browser.showSaveDialog(window);
					
					if (status == JFileChooser.APPROVE_OPTION) {
						p = browser.getSelectedFile().getPath();
						
						Save.saveFile(p);
					}
				}
			}
		});
		
		fileMenuClose.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				textArea.setText(null);
				isFileOpened = false;
				window.setTitle(title);
			}
		});

		quitButton.setContentAreaFilled(false);
		quitButton.setBorderPainted(false);
		quitButton.setFocusable(false);

		quitButton.addMouseListener(new java.awt.event.MouseAdapter() {
			public void mouseEntered(java.awt.event.MouseEvent evt) {
				quitButton.setContentAreaFilled(true);
				quitButton.setBackground(Color.RED);
			}

			public void mouseExited(java.awt.event.MouseEvent evt) {
				quitButton.setContentAreaFilled(false);
				quitButton.setBackground(UIManager.getColor("control"));
			}
		});

		quitButton.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				if (isFileOpened || !textArea.getText().isBlank()) {
					JOptionPane.showOptionDialog(window, "Do you want to save your work?", "Save before quit?", JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE, null, options, options[1]);
				} else {
					System.exit(0);
				}
			}
		});
		
		saveOptionDialogButton.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				if (isFileOpened) {
					Save.saveFile(p);
					System.exit(0);
				} else {
					status = browser.showSaveDialog(window);
					
					if (status == JFileChooser.APPROVE_OPTION) {
						p = browser.getSelectedFile().getPath();
						
						Save.saveFile(p);
						System.exit(0);
					}
				}
			}
		});
		
		discardOptionDialogButton.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				System.exit(0);
			}
		});

		fileExplorer.setBorder(new EtchedBorder());
		fileExplorer.setBackground(new Color(0, 0, 0));
		fileExplorer.setPreferredSize(new Dimension(200, 200));

		mainPanel.setLayout(new BorderLayout());
		mainPanel.setBorder(new EtchedBorder());
		mainPanel.add(scrollPane);

		textArea.setSyntaxEditingStyle(SyntaxConstants.SYNTAX_STYLE_CPLUSPLUS);
		textArea.setCodeFoldingEnabled(true);

		LanguageSupportFactory.get().register(textArea);

		autoComplete.install(textArea);

		window.add(fileExplorer, BorderLayout.WEST);
		window.add(mainPanel);

		window.setTitle(title);
		window.setSize(winSize);
		window.setJMenuBar(menuBar);
		window.setLocationRelativeTo(null);
		window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		window.setVisible(true);
	}

	public void build() {
		window = new JFrame();
		menuBar = new JMenuBar();
		fileMenu = new JMenu("File");
		editMenu = new JMenu("Edit");
		quitButton = new JButton("Quit");
		saveOptionDialogButton = new JButton("Save");
		discardOptionDialogButton = new JButton("Discard");
		options[0] = saveOptionDialogButton;
		options[1] = discardOptionDialogButton;
		fileMenuOpen = new JMenuItem("Open");
		fileMenuSave = new JMenuItem("Save");
		fileMenuClose = new JMenuItem("Close");
		browser = new JFileChooser("");
		fileExplorer = new JPanel();
		mainPanel = new JPanel();
		textArea = new RSyntaxTextArea();
		scrollPane = new RTextScrollPane(textArea);
		completionProvider = Providers.createCompletionProvider();
		autoComplete = new AutoCompletion(completionProvider);
	}

	@Override
	public void run() {
		build();
		setup();
	}

	public Window(String title, String version, Dimension winSize) {
		this.title = title + " " + version;
		this.winSize = winSize;
	}
}
