package kiyut.sketsa.modules.symbollibrary;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import javax.swing.Action;
import javax.swing.JPanel;
import kiyut.sketsa.actions.SaveAsAction;
import kiyut.sketsa.api.symbollibrary.Symbol;
import kiyut.sketsa.api.symbollibrary.SymbolLibrary;
import kiyut.sketsa.modules.symbollibrary.animal.ButterflySymbol;
import kiyut.sketsa.modules.symbollibrary.animal.DolphinSymbol;
import kiyut.sketsa.modules.symbollibrary.animal.RhinoSymbol;
import kiyut.sketsa.modules.symbollibrary.general.AtomSymbol;
import kiyut.sketsa.modules.symbollibrary.general.HeartSymbol;
import kiyut.sketsa.modules.symbollibrary.toilet.GentsSymbol;
import kiyut.sketsa.modules.symbollibrary.general.MoonSymbol;
import kiyut.sketsa.modules.symbollibrary.general.PolygonSymbol;
import kiyut.sketsa.modules.symbollibrary.general.StarSymbol;
import kiyut.sketsa.modules.symbollibrary.general.YinYangSymbol;
import kiyut.sketsa.modules.symbollibrary.toilet.LadiesSymbol;
import org.openide.util.SharedClassObject;

/**
 * Symbol Library Panel
 *
 * @author  Kiyut
 */
public class SymbolLibraryPane extends JPanel implements SymbolLibrary {
    private List<String> categoryList;
    private boolean categoryUpdating = false;
    
    /** Creates new form SymbolPane */
    public SymbolLibraryPane() {
        super();
        initComponents();
        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.
     */
    // <editor-fold defaultstate="collapsed" desc=" Generated Code ">//GEN-BEGIN:initComponents
    private void initComponents() {
        java.awt.GridBagConstraints gridBagConstraints;

        jScrollPane1 = new javax.swing.JScrollPane();
        symbolList = new javax.swing.JList();
        jToolBar1 = new javax.swing.JToolBar();
        categoryCombo = new javax.swing.JComboBox();

        setLayout(new java.awt.GridBagLayout());

        symbolList.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION);
        symbolList.setLayoutOrientation(javax.swing.JList.HORIZONTAL_WRAP);
        jScrollPane1.setViewportView(symbolList);

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 1;
        gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
        gridBagConstraints.weightx = 1.0;
        gridBagConstraints.weighty = 1.0;
        add(jScrollPane1, gridBagConstraints);

        jToolBar1.setFloatable(false);
        jToolBar1.setRollover(true);
        categoryCombo.setFocusable(false);
        jToolBar1.add(categoryCombo);

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
        add(jToolBar1, gridBagConstraints);

    }
    // </editor-fold>//GEN-END:initComponents
    
    
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JComboBox categoryCombo;
    private javax.swing.JScrollPane jScrollPane1;
    private javax.swing.JToolBar jToolBar1;
    private javax.swing.JList symbolList;
    // End of variables declaration//GEN-END:variables
    
    private void initCustomComponents() {
        // for performance reason, so the list doesn't need to compute from the cell
        symbolList.setFixedCellWidth(32);
        symbolList.setFixedCellHeight(32);
        
        symbolList.setDragEnabled(true);
        symbolList.setVisibleRowCount(-1);
        symbolList.setTransferHandler(new SymbolTransferHandler());
        
        SymbolRenderer renderer = new SymbolRenderer();
        symbolList.setCellRenderer(renderer);
        
        categoryList = new ArrayList<String>();
        
        symbolList.setModel(new SymbolListModel());
        
        // General
        addSymbol(new AtomSymbol());
        addSymbol(new HeartSymbol());
        addSymbol(new MoonSymbol());
        addSymbol(new PolygonSymbol());
        addSymbol(new StarSymbol());
        addSymbol(new YinYangSymbol());
        
        
        // Animal
        addSymbol(new ButterflySymbol());
        addSymbol(new DolphinSymbol());
        addSymbol(new RhinoSymbol());
        
        // Toilet
        addSymbol(new GentsSymbol());
        addSymbol(new LadiesSymbol());
        
        symbolList.addMouseListener(new MouseAdapter() {
            public void mouseClicked(MouseEvent evt) { symbolListMouseClicked(evt); }
        });
        
        categoryCombo.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent evt) {
                if (categoryUpdating == true) { return; }
                String category = (String)categoryCombo.getSelectedItem();
                if (category.equalsIgnoreCase("ALL")) {
                    category = null;
                }
                SymbolListModel model = (SymbolListModel)symbolList.getModel();
                model.setCategory(category);
            }
        });
    }
    
    /** add Symbol to the Library
     * @param symbol the Symbol to be added
     */
    public void addSymbol(Symbol symbol) {
        SymbolListModel model = (SymbolListModel)symbolList.getModel();
        model.addElement(symbol);
        updateCategoryList(symbol,true);
        
        
    }
    
    /** Remove the specifed symbol from the library
     * @param symbol the Symbol to be removed
     * @return true if success, otherwise false
     */
    public boolean removeSymbol(Symbol symbol) {
        SymbolListModel model = (SymbolListModel)symbolList.getModel();
        boolean b = model.removeElement(symbol);
        updateCategoryList(symbol,false);
        return b;
    }
    
    /** Update categoryList ComboBox item
     * @param symbol The <code>Symbol</code>
     * @param adding true for adding, false for removing
     */
    protected void updateCategoryList(Symbol symbol,boolean adding) {
        String category = symbol.getCategory();
        int indexOf = categoryList.indexOf(category);
        if (adding) {
            if (indexOf < 0) {
                categoryList.add(category);
                Collections.sort(categoryList);
            }
        } else {
            if (indexOf < 0) {
                return;
            }
            boolean exist = false;
            SymbolListModel model = (SymbolListModel)symbolList.getModel();
            for (int i=0; i < model.getSize(); i++) {
                Symbol tmpSymbol = (Symbol)model.getElementAt(i);
                if (tmpSymbol.getCategory().equals(category)) {
                    exist = true;
                    break;
                }
            }
            if (!exist) {
                categoryList.remove(category);
            }
        }
        
        categoryUpdating = true;
        try {
            //int index = categoryCombo.getSelectedIndex();
            categoryCombo.removeAllItems();
            categoryCombo.addItem("All");
            for (int i=0; i<categoryList.size();i++) {
                categoryCombo.addItem(categoryList.get(i));
            }
        } finally {
            categoryUpdating = false;
        }
    }
    
    //////////////////////////////////
    // Event Handler
    /////////////////////////////////
    private void symbolListMouseClicked(MouseEvent evt) {
        if (evt.getClickCount() != 2) { return; }
        int index = symbolList.locationToIndex(evt.getPoint());
        if (index < 0) { return; }
        Symbol item = (Symbol)symbolList.getModel().getElementAt(index);
        item.showOptionDialog(symbolList);
    }
}
