/*
 * Copyright (C) 1999-2006 <a href="mailto:adrian.paschke@gmx.de">Adrian Paschke</a>
 * 
 * The RBSLM Environment is part of the Rule Based Service Level Agreement (RBSLA)
 * framework, available at 
 * <a href=" http://ibis.in.tum.de/staff/paschke/rbsla/index.htm">RBSLA</a>
 * 
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

package rbsla.environment.dialogs;

import java.awt.Frame;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
import java.util.ArrayList;

import javax.swing.JDialog;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.text.BadLocationException;
import javax.swing.text.Element;

import org.apache.log4j.Logger;

import rbsla.wrapper.ProvaWrapper;
import rbsla.environment.ECAConstraints;
import rbsla.environment.ECAPanel;
import rbsla.environment.ECAWindow;

public class ProvaConsole extends JDialog implements ActionListener,
        KeyListener, WindowListener
{
    private Frame parentFrame;

    protected GridBagLayout myLayout;

    protected JTextArea textArea;

    private String inputRegelStr;

    private ProvaWrapper myProva;

    private String provaStartSyntax = ":-eval(";

    private String provaEndSyntax = ").";

    private ArrayList history = new ArrayList();

    //private String provaSyntaxPattern = "\\:\\-(\w*)eval\\((.*)\\)\\.";

    private static Logger logger = Logger.getLogger(ProvaConsole.class);

    public ProvaConsole(Frame parent, ProvaWrapper sla)
    {
        super(parent, "Rules Query Console");
        this.myProva = sla;

        parentFrame = parent;

        myLayout = new GridBagLayout();
        this.getContentPane().setLayout(myLayout);

        textArea = new JTextArea();

        // Add a scrolling text area
        textArea.addKeyListener(this);
        textArea.setEditable(true);
        textArea.setFont(ECAPanel.smallFont);
        textArea.setRows(20);
        textArea.setColumns(50);
        textArea.setLineWrap(true);
        textArea.setText("Console evaluates logical expressions. Use standard Prova syntax to ask question on current knowledge base.\n\n");

        JScrollPane scrollTextArea = new JScrollPane(textArea,
                JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
                JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
        getContentPane().add(
                scrollTextArea,
                new ECAConstraints(0, 0, 1, 1, 1.0, 1.0,
                        GridBagConstraints.NORTHWEST, GridBagConstraints.BOTH,
                        new Insets(0, 0, 5, 0), 0, 0));

        pack();

        if (parentFrame instanceof ECAWindow)
            ECAPanel.centerDialog(parentFrame, this);
        else
            ECAPanel.centerDialogOnScreen(this);

        getContentPane().addKeyListener(this);
        addWindowListener(this);

        setResizable(true);
        setVisible(true);
        textArea.requestFocus();

    }

    public void actionPerformed(ActionEvent E)
    {
    }

    public void keyPressed(KeyEvent E)
    {
        //inputRegelStr = inputRegelStr + E.getKeyText(E.getKeyCode());
        if (E.getKeyCode() == E.VK_UP || E.getKeyCode() == E.VK_DOWN)
            E.consume();
    }

    public void keyReleased(KeyEvent E)
    {
        if (E.getKeyCode() == E.VK_UP)
        {
            //textArea.append((String) history.get(history.size()-1));
            E.consume();
        } else if (E.getKeyCode() == E.VK_DOWN)
        {
            E.consume();
        }

        if (E.getKeyCode() == E.VK_ENTER)
        {
            /*
             * get last line of text area
             */
            // Get paragraph element
            Element paragraph = textArea.getDocument().getDefaultRootElement();

            // Get number of content elements
            int contentCount = paragraph.getElementCount();
            String lastLine = "";

            Element e = paragraph.getElement(contentCount - 2); //nur letzte
            // Zeile wird
            // benötigt.
            int rangeStart = e.getStartOffset();
            int rangeEnd = e.getEndOffset();
            try
            {
                lastLine = textArea.getText(rangeStart, rangeEnd - rangeStart);
                //System.out.println("line ["+0+"]"+"="+lastLine+" ");
            } catch (BadLocationException ex)
            {
                logger.info("", ex);
            }

            /*
             * get result from prova
             */
            //history.add(lastLine.substring(0,lastLine.length()-1));
            if (lastLine != null && lastLine.length() > 0
                    && lastLine.indexOf(provaStartSyntax) >= 0
                    && lastLine.indexOf(provaEndSyntax) >= 0)
            {
                String rs = sendToProva(lastLine);
                textArea.append(rs);
            } else
            {
                textArea.append("\n"
                        + "Syntax Error usage :-eval(math_add(2,3,X))." + "\n");
            }
            inputRegelStr = "";
        }

        if (E.getKeyCode() == E.VK_TAB)
        {
            if (E.getSource() == textArea)
            {
                // Tab out of the text area
                textArea.transferFocus();
                return;
            }
        }
    }

    public void keyTyped(KeyEvent E)
    {
    }

    public void windowActivated(WindowEvent E)
    {
    }

    public void windowClosed(WindowEvent E)
    {
    }

    public void windowClosing(WindowEvent E)
    {
        dispose();
    }

    public void windowDeactivated(WindowEvent E)
    {
    }

    public void windowDeiconified(WindowEvent E)
    {
    }

    public void windowIconified(WindowEvent E)
    {
    }

    public void windowOpened(WindowEvent E)
    {
    }

    private String sendToProva(String regelText)
    {
        int rangeStart = regelText.indexOf(provaStartSyntax) + 7;
        int rangeEnd = regelText.lastIndexOf(provaEndSyntax);
        String getParsedRegelStr = regelText.substring(rangeStart, rangeEnd);
        return myProva.getResultString(getParsedRegelStr) + "\n" ;
    }
}