/*
 *  RPGeneration - A role playing utility generate interesting things
 *  Copyright (C) 2002 Devon D Jones
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program 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 General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 *  The author of this program grants you the ability to use this code
 *  in conjunction with code that is covered under the Open Gaming License
 *
 * PersonalityFrame.java
 *
 * Created on October 23, 2002, 12:07 AM
 */

package org.evilsoft.gaming.RPGeneration;

import java.io.*;
import java.util.*;
import org.jdom.*;
import org.jdom.input.*;
import org.jdom.output.*;
import java.util.prefs.*;
import javax.swing.*;
import javax.swing.text.DefaultEditorKit;
import javax.swing.text.StyledEditorKit;
import javax.swing.text.StyleConstants;
import javax.swing.text.html.*;
import javax.swing.border.EtchedBorder;

/**
 *
 * @author  soulcatcher
 */
public class PersonalityFrame extends javax.swing.JFrame {

    /** Creates new form PersonalityFrame */
    public PersonalityFrame() {
        initComponents();
        initPrefs();
        initRest();
        initCustomComponents();
    }

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    private void initComponents() {//GEN-BEGIN:initComponents
        topTabs = new javax.swing.JTabbedPane();
        jPanel1 = new javax.swing.JPanel();
        jToolBar2 = new javax.swing.JToolBar();
        bCut = new javax.swing.JButton();
        bCopy = new javax.swing.JButton();
        bPaste = new javax.swing.JButton();
        jToolBar1 = new javax.swing.JToolBar();
        bBold = new javax.swing.JButton();
        bItalic = new javax.swing.JButton();
        bUnderline = new javax.swing.JButton();
        fontSize = new javax.swing.JComboBox();
        jMenuBar1 = new javax.swing.JMenuBar();
        mFile = new javax.swing.JMenu();
        mSave = new javax.swing.JMenuItem();
        mEdit = new javax.swing.JMenu();
        mCut = new javax.swing.JMenuItem();
        mCopy = new javax.swing.JMenuItem();
        mPaste = new javax.swing.JMenuItem();
        mStyle = new javax.swing.JMenu();
        mBold = new javax.swing.JMenuItem();
        mItalic = new javax.swing.JMenuItem();
        mUnderline = new javax.swing.JMenuItem();
        mHelp = new javax.swing.JMenu();
        mAbout = new javax.swing.JMenuItem();

        setTitle("RPGeneration");
        addWindowListener(new java.awt.event.WindowAdapter() {
            public void windowClosing(java.awt.event.WindowEvent evt) {
                exitForm(evt);
            }
        });

        topTabs.setPreferredSize(new java.awt.Dimension(522, 500));
        getContentPane().add(topTabs, java.awt.BorderLayout.CENTER);

        jPanel1.setLayout(new java.awt.FlowLayout(java.awt.FlowLayout.LEFT));

        bCut.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/evilsoft/gaming/RPGeneration/stock_cut-16.png")));
        bCut.setToolTipText("Cut");
        bCut.setBorder(new javax.swing.border.EtchedBorder());
        bCut.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                bCutActionPerformed(evt);
            }
        });

        jToolBar2.add(bCut);

        bCopy.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/evilsoft/gaming/RPGeneration/stock_copy-16.png")));
        bCopy.setToolTipText("Copy");
        bCopy.setBorder(new javax.swing.border.EtchedBorder());
        bCopy.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                bCopyActionPerformed(evt);
            }
        });

        jToolBar2.add(bCopy);

        bPaste.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/evilsoft/gaming/RPGeneration/stock_paste-16.png")));
        bPaste.setToolTipText("Paste");
        bPaste.setBorder(new javax.swing.border.EtchedBorder());
        bPaste.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                bPasteActionPerformed(evt);
            }
        });

        jToolBar2.add(bPaste);

        jPanel1.add(jToolBar2);

        bBold.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/evilsoft/gaming/RPGeneration/stock_text_bold-16.png")));
        bBold.setToolTipText("Bold");
        bBold.setBorder(new javax.swing.border.EtchedBorder());
        bBold.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                bBoldActionPerformed(evt);
            }
        });

        jToolBar1.add(bBold);

        bItalic.setFont(new java.awt.Font("Dialog", 2, 12));
        bItalic.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/evilsoft/gaming/RPGeneration/stock_text_italic-16.png")));
        bItalic.setToolTipText("Italic");
        bItalic.setBorder(new javax.swing.border.EtchedBorder());
        bItalic.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                bItalicActionPerformed(evt);
            }
        });

        jToolBar1.add(bItalic);

        bUnderline.setFont(new java.awt.Font("Dialog", 0, 12));
        bUnderline.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/evilsoft/gaming/RPGeneration/stock_text_underline-16.png")));
        bUnderline.setToolTipText("Underline");
        bUnderline.setBorder(new javax.swing.border.EtchedBorder());
        bUnderline.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                bUnderlineActionPerformed(evt);
            }
        });

        jToolBar1.add(bUnderline);

        fontSize.setToolTipText("Font Size");
        fontSize.setBorder(new javax.swing.border.EtchedBorder());
        fontSize.setMinimumSize(new java.awt.Dimension(50, 25));
        fontSize.setPreferredSize(new java.awt.Dimension(50, 25));
        fontSize.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                fontSizeActionPerformed(evt);
            }
        });

        jToolBar1.add(fontSize);

        jPanel1.add(jToolBar1);

        getContentPane().add(jPanel1, java.awt.BorderLayout.NORTH);

        mFile.setText("File");
        mSave.setText("Save");
        mSave.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                mSaveActionPerformed(evt);
            }
        });

        mFile.add(mSave);
        jMenuBar1.add(mFile);
        mEdit.setText("Edit");
        mCut.setText("Cut");
        mCut.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                mCutActionPerformed(evt);
            }
        });

        mEdit.add(mCut);
        mCopy.setText("Copy");
        mCopy.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                mCopyActionPerformed(evt);
            }
        });

        mEdit.add(mCopy);
        mPaste.setText("Paste");
        mPaste.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                mPasteActionPerformed(evt);
            }
        });

        mEdit.add(mPaste);
        jMenuBar1.add(mEdit);
        mStyle.setText("Style");
        mBold.setText("Bold");
        mBold.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                mBoldActionPerformed(evt);
            }
        });

        mStyle.add(mBold);
        mItalic.setText("Italic");
        mItalic.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                mItalicActionPerformed(evt);
            }
        });

        mStyle.add(mItalic);
        mUnderline.setText("Underline");
        mUnderline.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                mUnderlineActionPerformed(evt);
            }
        });

        mStyle.add(mUnderline);
        jMenuBar1.add(mStyle);
        mHelp.setText("Help");
        mAbout.setText("About");
        mAbout.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                mAboutActionPerformed(evt);
            }
        });

        mHelp.add(mAbout);
        jMenuBar1.add(mHelp);
        setJMenuBar(jMenuBar1);

        pack();
    }//GEN-END:initComponents

    private void mSaveActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_mSaveActionPerformed
        JFileChooser chooser = new JFileChooser();
        SaveFileFilter filter = new SaveFileFilter();
        chooser.setFileFilter(filter);
        int returnVal = chooser.showSaveDialog(this);
        if(returnVal == JFileChooser.APPROVE_OPTION) {
            try {
                GeneratorPanel panel = (GeneratorPanel)topTabs.getSelectedComponent();
                JTextPane textPane = panel.getCurrentJTextPane();
                HTMLDocument htDoc = (HTMLDocument)textPane.getStyledDocument();
                FileWriter fw = new FileWriter(chooser.getSelectedFile());
                HTMLWriter hw = new HTMLWriter(fw, htDoc);
                hw.write();
                fw.flush();
                fw.close();
            }
            catch(Exception e) {
                JDialog jd = new JDialog(this, e.getMessage(), true);
                jd.show();
            }
        }
    }//GEN-LAST:event_mSaveActionPerformed

    private void fontSizeActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_fontSizeActionPerformed
        String fontS = (String)fontSize.getSelectedItem();
        performTextPaneAction("font-size-" + fontS, evt);
    }//GEN-LAST:event_fontSizeActionPerformed

    private void bPasteActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_bPasteActionPerformed
        performTextPaneAction(DefaultEditorKit.pasteAction, evt);
    }//GEN-LAST:event_bPasteActionPerformed

    private void bCopyActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_bCopyActionPerformed
        performTextPaneAction(DefaultEditorKit.copyAction, evt);
    }//GEN-LAST:event_bCopyActionPerformed

    private void bCutActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_bCutActionPerformed
        performTextPaneAction(DefaultEditorKit.cutAction, evt);
    }//GEN-LAST:event_bCutActionPerformed

    private void bBoldActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_bBoldActionPerformed
        performTextPaneAction("font-bold", evt);
    }//GEN-LAST:event_bBoldActionPerformed

    private void bItalicActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_bItalicActionPerformed
        performTextPaneAction("font-italic", evt);
    }//GEN-LAST:event_bItalicActionPerformed

    private void bUnderlineActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_bUnderlineActionPerformed
        performTextPaneAction("font-underline", evt);
    }//GEN-LAST:event_bUnderlineActionPerformed

    private void mUnderlineActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_mUnderlineActionPerformed
        performTextPaneAction("font-underline", evt);
    }//GEN-LAST:event_mUnderlineActionPerformed

    private void mItalicActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_mItalicActionPerformed
        performTextPaneAction("font-italic", evt);
    }//GEN-LAST:event_mItalicActionPerformed

    private void mBoldActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_mBoldActionPerformed
        performTextPaneAction("font-bold", evt);
    }//GEN-LAST:event_mBoldActionPerformed

    private void mPasteActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_mPasteActionPerformed
        performTextPaneAction(DefaultEditorKit.pasteAction, evt);
    }//GEN-LAST:event_mPasteActionPerformed

    private void mCopyActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_mCopyActionPerformed
        performTextPaneAction(DefaultEditorKit.copyAction, evt);
    }//GEN-LAST:event_mCopyActionPerformed

    private void mCutActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_mCutActionPerformed
        performTextPaneAction(DefaultEditorKit.cutAction, evt);
    }//GEN-LAST:event_mCutActionPerformed

    private void mAboutActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_mAboutActionPerformed
        // Add your handling code here:
        AboutBox dialog = new AboutBox(this, true, VERSION);
        dialog.setVisible(true);
    }//GEN-LAST:event_mAboutActionPerformed

    /** Exit the Application */
    private void exitForm(java.awt.event.WindowEvent evt) {//GEN-FIRST:event_exitForm
        prefs.putInt("WindowX", this.getX());
        prefs.putInt("WindowY", this.getY());
        prefs.putInt("WindowWidth", this.getSize().width);
        prefs.putInt("WindowHeight", this.getSize().height);
        System.exit(0);
    }//GEN-LAST:event_exitForm

    /**
     * @param args the command line arguments
     */
    public static void main(String args[]) {
        new PersonalityFrame().show();
    }

    private void initPrefs() {
        boolean prefsSet = prefs.getBoolean("arePrefsSet", false);
//        PrefsSet = false;
        if(!prefsSet) {
            prefs.putBoolean("arePrefsSet", true);
        }
        double version = prefs.getDouble("Version", 0);
        if(version < 0.91 || !prefsSet) {
            prefs.putDouble("Version", 0.91);
        }
        int iWinX = prefs.getInt("WindowX", 0);
        int iWinY = prefs.getInt("WindowY", 0);
        this.setLocation(iWinX, iWinY);

        int iWinWidth = prefs.getInt("WindowWidth", 500);
        int iWinHeight = prefs.getInt("WindowHeight", 500);
        this.setSize(iWinWidth, iWinHeight);
    }

    public void initRest() {
        try {
            File defaultFile = new File("./config.xml");
            SAXBuilder builder = new SAXBuilder();
            Document configXML = builder.build(defaultFile);
            if(configXML.getRootElement().getName().equals("Config")) {
                Element config = configXML.getRootElement();
                List tabs = config.getChildren("Tab");
                ListIterator tabsIterator = tabs.listIterator();
                while(tabsIterator.hasNext()) {
                    Element tabElement = (Element)tabsIterator.next();
                    String directory = "";
                    String topPanel = "";
                    String title = "";

                    if(tabElement.getAttribute("Directory") != null) {
                        directory = tabElement.getAttribute("Directory").getValue();
                    }
                    if(tabElement.getAttribute("TopPanel") != null) {
                        topPanel = tabElement.getAttribute("TopPanel").getValue();
                    }
                    if(tabElement.getAttribute("Title") != null) {
                        title = tabElement.getAttribute("Title").getValue();
                    }
                    try {
                        Class c = Class.forName("org.evilsoft.gaming.RPGeneration." + topPanel);
                        TopPanel newTopPanel = (TopPanel)c.newInstance();
                        topTabs.addTab(title, new GeneratorPanel(this, tables, newTopPanel, directory));
                    }
                    catch (Exception e)
                    {
                        System.out.println(e);
                    }
                }
            }
        }
        catch(Exception e) {
            System.out.println("XML ERROR");
            e.printStackTrace();
        }
    }
    
    private void initCustomComponents() {
        Vector fontVector = new Vector();
        fontVector.add("8");
        fontVector.add("10");
        fontVector.add("12");
        fontVector.add("14");
        fontVector.add("16");
        fontVector.add("18");
        fontVector.add("24");
        fontVector.add("36");
        fontVector.add("48");
        javax.swing.DefaultComboBoxModel cbModel = new javax.swing.DefaultComboBoxModel(fontVector);
        fontSize.setModel(cbModel);
        stdBold();
        stdItalic();
        stdUnderline();
        bCut.setBorder(new EtchedBorder(EtchedBorder.LOWERED));
        bCopy.setBorder(new EtchedBorder(EtchedBorder.LOWERED));
        bPaste.setBorder(new EtchedBorder(EtchedBorder.LOWERED));
        fontSize.setBorder(new EtchedBorder(EtchedBorder.LOWERED));
    }
    private void performTextPaneAction(String name, java.awt.event.ActionEvent evt) {
        GeneratorPanel panel = (GeneratorPanel)topTabs.getSelectedComponent();
        JTextPane textPane = panel.getCurrentJTextPane();
        Action action = panel.getActionByName(textPane, name);
        action.actionPerformed(evt);
        textPane.grabFocus();
        int cp = textPane.getCaretPosition();
        updateButtons(textPane, cp);
    }
    
    public void updateButtons(JTextPane textPane, int pos) {
        javax.swing.text.StyledDocument doc = textPane.getStyledDocument();
        javax.swing.text.AttributeSet set = doc.getCharacterElement(pos - 1).getAttributes();
        if (StyleConstants.isBold(set)) {
            highlightBold();
        }
        else {
            stdBold();
        }
        
        if (StyleConstants.isItalic(set)) {
            highlightItalic();
        }
        else {
            stdItalic();
        }

        if (StyleConstants.isUnderline(set)) {
            highlightUnderline();
        }
        else {
            stdUnderline();
        }
        
        int size = StyleConstants.getFontSize(set);
    }

    private void highlightBold() {
        bBold.setBorder(new EtchedBorder(EtchedBorder.RAISED));
    }

    private void stdBold() {
        bBold.setBorder(new EtchedBorder(EtchedBorder.LOWERED));
    }
    
    private void highlightItalic() {
        bItalic.setBorder(new EtchedBorder(EtchedBorder.RAISED));
    }
    
    private void stdItalic() {
        bItalic.setBorder(new EtchedBorder(EtchedBorder.LOWERED));
    }

    private void highlightUnderline() {
        bUnderline.setBorder(new EtchedBorder(EtchedBorder.RAISED));
    }

    private void stdUnderline() {
        bUnderline.setBorder(new EtchedBorder(EtchedBorder.LOWERED));
    }

    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JMenuItem mUnderline;
    private javax.swing.JButton bCopy;
    private javax.swing.JToolBar jToolBar2;
    private javax.swing.JMenu mStyle;
    private javax.swing.JComboBox fontSize;
    private javax.swing.JButton bPaste;
    private javax.swing.JMenu mEdit;
    private javax.swing.JButton bBold;
    private javax.swing.JMenu mHelp;
    private javax.swing.JMenuItem mPaste;
    private javax.swing.JMenuItem mBold;
    private javax.swing.JToolBar jToolBar1;
    private javax.swing.JMenuItem mItalic;
    private javax.swing.JButton bItalic;
    private javax.swing.JMenuItem mAbout;
    private javax.swing.JButton bUnderline;
    private javax.swing.JMenu mFile;
    private javax.swing.JTabbedPane topTabs;
    private javax.swing.JMenuItem mCut;
    private javax.swing.JPanel jPanel1;
    private javax.swing.JMenuItem mSave;
    private javax.swing.JMenuItem mCopy;
    private javax.swing.JButton bCut;
    private javax.swing.JMenuBar jMenuBar1;
    // End of variables declaration//GEN-END:variables
    private boolean panesClear = true;
    private String nameDefault;
    private Preferences prefs = Preferences.userNodeForPackage(PersonalityFrame.class);
    private HashMap tables = new HashMap();
    private final String VERSION = "0.9.1";
}

