package istlab.KisoJikken;

import java.awt.BorderLayout;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.plaf.FontUIResource;

import org.fife.ui.autocomplete.AutoCompletion;
import org.fife.ui.autocomplete.BasicCompletion;
import org.fife.ui.autocomplete.CompletionProvider;
import org.fife.ui.autocomplete.DefaultCompletionProvider;
import org.fife.ui.autocomplete.ShorthandCompletion;
import org.fife.ui.rsyntaxtextarea.RSyntaxTextArea;
import org.fife.ui.rsyntaxtextarea.SyntaxConstants;
import org.fife.ui.rtextarea.RTextScrollPane;
import org.mdkt.compiler.InMemoryJavaCompiler;

public class AutoCompleteDemo extends JFrame {

   RSyntaxTextArea textArea;

   public AutoCompleteDemo() {

      JPanel contentPane = new JPanel(new BorderLayout());
      textArea = new RSyntaxTextArea(20, 60);
      textArea.setSyntaxEditingStyle(SyntaxConstants.SYNTAX_STYLE_JAVA);
      textArea.setCodeFoldingEnabled(true);
      textArea.setFont(new FontUIResource("sansserif", Font.PLAIN, 20));
      contentPane.add(new RTextScrollPane(textArea));

      // A CompletionProvider is what knows of all possible completions, and
      // analyzes the contents of the text area at the caret position to
      // determine what completion choices should be presented. Most instances
      // of CompletionProvider (such as DefaultCompletionProvider) are designed
      // so that they can be shared among multiple text components.
      CompletionProvider provider = createCompletionProvider();

      // An AutoCompletion acts as a "middle-man" between a text component
      // and a CompletionProvider. It manages any options associated with
      // the auto-completion (the popup trigger key, whether to display a
      // documentation window along with completion choices, etc.). Unlike
      // CompletionProviders, instances of AutoCompletion cannot be shared
      // among multiple text components.
      AutoCompletion ac = new AutoCompletion(provider);
      ac.install(textArea);

      setContentPane(contentPane);
      setTitle("AutoComplete Demo");
      setDefaultCloseOperation(EXIT_ON_CLOSE);

      JPanel north = new JPanel();
      JButton loadB = new JButton("Load");
      loadB.addActionListener(new ActionListener() {
         @Override
         public void actionPerformed(ActionEvent e) {
            InputStream is = getClass().getResourceAsStream("/Hello.java");
            BufferedReader br = new BufferedReader(new InputStreamReader(is));
            StringBuilder sb = new StringBuilder();
            String line;
            try {
               while((line=br.readLine())!=null){
                  sb.append(line+"\n");
               }
            } catch (IOException e1) {
               e1.printStackTrace();
            }
            textArea.setText(sb.toString());

         }
      });
      north.add(loadB);

      JButton saveB = new JButton("Save");
      saveB.addActionListener(new ActionListener() {
         @Override
         public void actionPerformed(ActionEvent e) {
            System.out.println(textArea.getText());
         }
      });
      north.add(saveB);

      JButton execB = new JButton("Exec");
      execB.addActionListener(new ActionListener() {
         @Override
         public void actionPerformed(ActionEvent e) {
            Class<?> helloClass;
            try {
               helloClass = InMemoryJavaCompiler.newInstance().compile("Hello", textArea.getText());
               System.out.println(helloClass.getClass().getName());

               System.out.println(helloClass.getDeclaredConstructor().newInstance().toString());
            } catch (Exception e1) {
               e1.printStackTrace();
            }

         }
      });
      north.add(execB);
      // JOptionPane.showMessageDialog(null, "test");

      add(north, BorderLayout.NORTH);
      pack();
      setLocationRelativeTo(null);


   }

   /**
    * Create a simple provider that adds some Java-related completions.
    */
   private CompletionProvider createCompletionProvider() {

      // A DefaultCompletionProvider is the simplest concrete implementation
      // of CompletionProvider. This provider has no understanding of
      // language semantics. It simply checks the text entered up to the
      // caret position for a match against known completions. This is all
      // that is needed in the majority of cases.
      DefaultCompletionProvider provider = new DefaultCompletionProvider();

      // Add completions for all Java keywords. A BasicCompletion is just
      // a straightforward word completion.
      provider.addCompletion(new BasicCompletion(provider, "abstract"));
      provider.addCompletion(new BasicCompletion(provider, "assert"));
      provider.addCompletion(new BasicCompletion(provider, "break"));
      provider.addCompletion(new BasicCompletion(provider, "case"));
      // ... etc ...
      provider.addCompletion(new BasicCompletion(provider, "transient"));
      provider.addCompletion(new BasicCompletion(provider, "try"));
      provider.addCompletion(new BasicCompletion(provider, "void"));
      provider.addCompletion(new BasicCompletion(provider, "volatile"));
      provider.addCompletion(new BasicCompletion(provider, "while"));

      // Add a couple of "shorthand" completions. These completions don't
      // require the input text to be the same thing as the replacement text.
      provider.addCompletion(new ShorthandCompletion(provider, "sysout",
            "System.out.println(", "System.out.println("));
      provider.addCompletion(new ShorthandCompletion(provider, "syserr",
            "System.err.println(", "System.err.println("));

      return provider;

   }

   public static void main(String[] args) {
      // Instantiate GUI on the EDT.
      SwingUtilities.invokeLater(() -> {
         try {
            String laf = UIManager.getSystemLookAndFeelClassName();
            UIManager.setLookAndFeel(laf);
         } catch (Exception e) {
            /* Never happens */ }
         new AutoCompleteDemo().setVisible(true);
      });
   }

}