/*
 * Copyright (C) 2018 Tom Almy
 *
 * 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 3 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, see <http://www.gnu.org/licenses/>.
 */
package us.almy.jelbumpro;

import java.util.LinkedList;

/**
 *
 * @author tom
 */
public class JumbleWordPanel extends javax.swing.JPanel {
    private final JelbumSolver solver;

    /**
     * Creates new form JumbleWordPanel
     */
    public JumbleWordPanel() {
        solver = new JelbumSolver();
        initComponents();
    }

    /**
     * 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.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        jButton1 = new javax.swing.JButton();
        jButton2 = new javax.swing.JButton();
        characterField = new javax.swing.JTextField();
        patternField = new javax.swing.JTextField();
        errorLabel = new javax.swing.JLabel();
        jScrollPane1 = new javax.swing.JScrollPane();
        resultList = new javax.swing.JList<>();
        jLabel1 = new javax.swing.JLabel();
        jLabel2 = new javax.swing.JLabel();
        jLabel3 = new javax.swing.JLabel();

        jButton1.setText("jButton1");

        jButton2.setText("jButton2");

        setBorder(javax.swing.BorderFactory.createLineBorder(new java.awt.Color(0, 0, 0)));
        setPreferredSize(new java.awt.Dimension(240, 121));

        errorLabel.setText("Error Message");

        resultList.setEnabled(false);
        jScrollPane1.setViewportView(resultList);

        jLabel1.setText("First Word");

        jLabel2.setText("Characters");

        jLabel3.setText("Pattern");

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
        this.setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(errorLabel, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addComponent(jLabel3)
                            .addComponent(jLabel2))
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addComponent(patternField, javax.swing.GroupLayout.PREFERRED_SIZE, 103, javax.swing.GroupLayout.PREFERRED_SIZE)
                            .addComponent(characterField, javax.swing.GroupLayout.PREFERRED_SIZE, 103, javax.swing.GroupLayout.PREFERRED_SIZE))
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 110, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
                    .addGroup(layout.createSequentialGroup()
                        .addComponent(jLabel1)
                        .addGap(0, 0, Short.MAX_VALUE)))
                .addContainerGap())
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(jLabel1)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(layout.createSequentialGroup()
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                            .addComponent(characterField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                            .addComponent(jLabel2))
                        .addGap(0, 0, Short.MAX_VALUE))
                    .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                        .addGap(8, 8, 8)
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                                .addComponent(patternField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                                .addComponent(jLabel3))
                            .addComponent(jScrollPane1, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.PREFERRED_SIZE, 62, javax.swing.GroupLayout.PREFERRED_SIZE))))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                .addComponent(errorLabel)
                .addContainerGap())
        );
    }// </editor-fold>//GEN-END:initComponents


    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JTextField characterField;
    private javax.swing.JLabel errorLabel;
    private javax.swing.JButton jButton1;
    private javax.swing.JButton jButton2;
    private javax.swing.JLabel jLabel1;
    private javax.swing.JLabel jLabel2;
    private javax.swing.JLabel jLabel3;
    private javax.swing.JScrollPane jScrollPane1;
    private javax.swing.JTextField patternField;
    private javax.swing.JList<String> resultList;
    // End of variables declaration//GEN-END:variables

    String pattern;
    AWord theWord;
    int selectCount;
    
    /**
     * Clear all the fields
     */
    public void clearPanel() {
        characterField.setText("");
        errorLabel.setText("");
        patternField.setText("");
        String[] strings = {};
        resultList.setListData(strings);
        resultList.setEnabled(false);
    }
    
    /**
     * Labels the panel and reads the dictionary file, if necessary
     * @param s name of the panel, such as "First Word"
     */
    public void setLabel(String s) {
        jLabel1.setText(s);
        solver.readWords(); // We need to do it somewhere
    }
    
    /**
     * Sets things up for eventual solving. This lets us catch errors before
     * solving anything
     * @return true upon success
     */
    public boolean verifyData() {
        // Check all data fields for validity and set error field if something is wrong
        theWord = solver.makeAWord(characterField.getText());
        if (theWord == null) {
            errorLabel.setText("characters must be only lowercase letters");
            return false;
        }
        pattern = patternField.getText();
        selectCount = 0;
        for (int i=0; i< pattern.length(); i++) {
            char ch = pattern.charAt(i);
            if (ch != 'o' && ch != '-') {
                errorLabel.setText("pattern must consist of only '-' and 'o' characters");
                return false;
            }
            if (ch == 'o') {
                selectCount++;
            }
        }
        if (pattern.length() != theWord.length) {
            errorLabel.setText("characters and pattern must be same length");
            return false;
        }
        errorLabel.setText("");
        return true;
    }

    /**
     * Solve the word
     * @return true if successful (at least one solution)
     */
    public boolean process() {
        // Process the word. Return true if there is at least one solution, which
        // includes a non-contributing (empty) word.
        if (theWord.length == 0) return true;
        LinkedList<String> answerText = new LinkedList<>();
        LinkedList<Integer> patternList = new LinkedList<>();
        patternList.add(theWord.length);
        solver.solve("", patternList, theWord, answerText);
        // There should be something easier than this!!
        Object[] answers = answerText.toArray();
        String[] ans = new String[answers.length];
        for (int i = 0; i < ans.length; i++) {
            ans[i] = (String)answers[i];
        }        
        resultList.setListData(ans);
        resultList.setSelectedIndex(0);
        resultList.setEnabled(true);
        return answers.length>0;
    }
    
    /**
     * Get the selected characters of the selected solution
     * @return the selected characters
     */
    public String getSelectedSolution() {
        if (theWord.length == 0) return "";
        StringBuilder sb = new StringBuilder();
        String theResult = resultList.getSelectedValue();
        if (theResult==null) return "";
        for (int i = 0; i < theResult.length(); i++) {
            if (pattern.charAt(i) == 'o') sb.append(theResult.charAt(i));
        }
        return sb.toString();
    }
    
}
