/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package csa.tiletools.sprites;

import csa.tiletools.sprites.*;
import csa.gui.components.CSAView;
import csa.tiletools.graphics.BaseImageData;
import csa.tiletools.graphics.ImageSequenceData;
import java.awt.Component;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable;
import java.util.HashMap;
import java.util.Vector;
import javax.swing.TransferHandler;
import csa.config.Configuration;
import csa.gui.Windowable;
import csa.gui.components.CSAView;
import csa.gui.dialogs.InternalFrameFileChoser;
import csa.gui.ImageCache;
import csa.gui.image.OctTreeQuantizer;
import csa.tiletools.graphics.BaseImageData;
import csa.tiletools.graphics.ClickListener;
import csa.tiletools.graphics.ImageComponent;
import csa.tiletools.graphics.ImageSequence;
import csa.tiletools.graphics.ImageSequenceData;
import csa.tiletools.graphics.ImageSequenceDataPool;
import csa.tiletools.graphics.MustSaveAsOneDialog;
import csa.tiletools.graphics.OriginJPanel;
import csa.tiletools.script.ExportFrame;
import csa.tiletools.tiles.Tile;
import csa.tiletools.tiles.TileData;
import csa.tiletools.tiles.TileDataPool;
import csa.tiletools.worldgen.heroextant.ElevationGenerationPhase;
import csa.tiletools.worldgen.heroextant.Hemisphere;
import csa.tiletools.worldgen.heroextant.TileType;
import csa.tiletools.worldgen.heroextant.WorldGenerator;
import csa.tiletools.worldgen.heroextant.maptoolkit.data.DenseMapData;
import csa.tiletools.worldgen.mapgen.MapGen;
import csa.tiletools.worldgen.worldgen.WorldGen;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Image;
import java.awt.Point;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.StringSelection;
import java.awt.datatransfer.Transferable;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionListener;
import java.awt.image.BufferedImage;
import java.awt.image.WritableRaster;
import java.io.File;
import java.util.*;
import javax.swing.BorderFactory;
import javax.swing.ImageIcon;
import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTable;
import javax.swing.SwingUtilities;
import javax.swing.TransferHandler;
import javax.swing.border.Border;
import javax.swing.filechooser.FileNameExtensionFilter;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.TableCellRenderer;
import net.sourceforge.jiu.color.quantization.MedianCutQuantizer;
import net.sourceforge.jiu.color.quantization.OctreeColorQuantizer;
import net.sourceforge.jiu.color.quantization.PopularityQuantizer;
import net.sourceforge.jiu.gui.awt.BufferedRGB24Image;

/**
 *
 * @author salchr
 */
public class ImageDragSourcePanel extends javax.swing.JPanel implements Windowable{

    HashMap<String, TileData> tileCache = new HashMap<String, TileData>();

    Vector <TileData> mAllTilesInClass = new Vector <TileData>();
    private TileDataPool mTileDataPool = null;
    private int mClassSetting=0;
    private CSAView mParent = null;
    private javax.swing.JMenuItem mParentMenuItem = null;
    boolean notDragged = true;
    TileData mCurrentTile=null;

    int inSetting;    
    
    JPanel currentSelectedTileImagePanel = null;
    
    @Override
    public void closing(){}
    @Override
    public void setParentWindow(CSAView jpv)
    {
        mParent = jpv;
    }
    @Override
    public void setMenuItem(javax.swing.JMenuItem item)
    {
        mParentMenuItem = item;
        mParentMenuItem.setText("Sprite Selector");
    }
    @Override
    public javax.swing.JMenuItem getMenuItem()
    {
        return mParentMenuItem;
    }
    @Override
    public javax.swing.JPanel getPanel()
    {
        return this;
    }
    
    /**
     * Creates new form TileSelectionDragSourcePanel
     */
    public ImageDragSourcePanel() {
        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() {

        jPanel1 = new javax.swing.JPanel();
        jLabel4 = new javax.swing.JLabel();
        jLabel5 = new javax.swing.JLabel();
        jTextFieldTileFile = new javax.swing.JTextField();
        jButtonFileSelect1 = new javax.swing.JButton();
        jComboBoxKlasse = new javax.swing.JComboBox();
        jPanel16 = new javax.swing.JPanel();
        jScrollPane9 = new javax.swing.JScrollPane();
        jPanelIMageCollection1 = new javax.swing.JPanel();
        jPanel17 = new javax.swing.JPanel();

        jPanel1.setBorder(javax.swing.BorderFactory.createTitledBorder("Tile Set"));

        jLabel4.setText("Class");

        jLabel5.setText("Filename");

        jTextFieldTileFile.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jTextFieldTileFileActionPerformed(evt);
            }
        });
        jTextFieldTileFile.addFocusListener(new java.awt.event.FocusAdapter() {
            public void focusLost(java.awt.event.FocusEvent evt) {
                jTextFieldTileFileFocusLost(evt);
            }
        });

        jButtonFileSelect1.setText("...");
        jButtonFileSelect1.setMargin(new java.awt.Insets(0, 1, 0, -1));
        jButtonFileSelect1.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButtonFileSelect1ActionPerformed(evt);
            }
        });

        jComboBoxKlasse.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jComboBoxKlasseActionPerformed(evt);
            }
        });

        javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
        jPanel1.setLayout(jPanel1Layout);
        jPanel1Layout.setHorizontalGroup(
            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel1Layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(jLabel5)
                    .addComponent(jLabel4))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(jComboBoxKlasse, javax.swing.GroupLayout.PREFERRED_SIZE, 145, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addGroup(jPanel1Layout.createSequentialGroup()
                        .addComponent(jTextFieldTileFile, javax.swing.GroupLayout.PREFERRED_SIZE, 128, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(jButtonFileSelect1)))
                .addContainerGap(12, Short.MAX_VALUE))
        );
        jPanel1Layout.setVerticalGroup(
            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel1Layout.createSequentialGroup()
                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jLabel5)
                    .addComponent(jTextFieldTileFile, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jButtonFileSelect1))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(jLabel4)
                    .addComponent(jComboBoxKlasse, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)))
        );

        jPanel16.setBorder(javax.swing.BorderFactory.createTitledBorder("Tile Collection"));
        jPanel16.setAlignmentX(1.0F);

        jScrollPane9.setHorizontalScrollBarPolicy(javax.swing.ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
        jScrollPane9.setVerticalScrollBarPolicy(javax.swing.ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);

        jPanelIMageCollection1.setMinimumSize(new java.awt.Dimension(20, 20));
        jPanelIMageCollection1.setLayout(null);

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

        javax.swing.GroupLayout jPanel17Layout = new javax.swing.GroupLayout(jPanel17);
        jPanel17.setLayout(jPanel17Layout);
        jPanel17Layout.setHorizontalGroup(
            jPanel17Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 50, Short.MAX_VALUE)
        );
        jPanel17Layout.setVerticalGroup(
            jPanel17Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 50, Short.MAX_VALUE)
        );

        jPanelIMageCollection1.add(jPanel17);
        jPanel17.setBounds(5, 5, 52, 52);

        jScrollPane9.setViewportView(jPanelIMageCollection1);

        javax.swing.GroupLayout jPanel16Layout = new javax.swing.GroupLayout(jPanel16);
        jPanel16.setLayout(jPanel16Layout);
        jPanel16Layout.setHorizontalGroup(
            jPanel16Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(jScrollPane9)
        );
        jPanel16Layout.setVerticalGroup(
            jPanel16Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(jScrollPane9, javax.swing.GroupLayout.DEFAULT_SIZE, 385, Short.MAX_VALUE)
        );

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
        this.setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(jPanel16, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
            .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jPanel16, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );
    }// </editor-fold>//GEN-END:initComponents

    private void jTextFieldTileFileActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jTextFieldTileFileActionPerformed

        loadTileCollection();
    }//GEN-LAST:event_jTextFieldTileFileActionPerformed
    public void loadTileCollection()
    {
        String file = jTextFieldTileFile.getText().trim();
        //if (jComboBoxKlasse.getSelectedIndex()==-1) return;
        String _class = "";
        if (file.length() == 0) return;

        mTileDataPool = new TileDataPool("Tile"+File.separator+file+".xml");
        if (mTileDataPool == null) return;

        resetConfigPool(true, _class, "");
    }
    private void resetCompositeCache()
    {
    }

    // Config Pool for TileMap
    private void resetConfigPool(boolean select, String klasseToSet, String tileToSet) /* allneeded*/
    {
        //if (mClassSetting>=0) return;
        mClassSetting++;
        resetCompositeCache();
        jComboBoxKlasse.removeAllItems();
        mClassSetting--;
        if (mTileDataPool == null) return;

        mClassSetting++;
        Collection<String> collectionKlasse = mTileDataPool.getKlassenHashMap().values();
        Iterator<String> iterKlasse = collectionKlasse.iterator();
        int i = 0;
        String klasse = "";

        while (iterKlasse.hasNext())
        {
            String item = iterKlasse.next();
            jComboBoxKlasse.addItem(item);
            if (select)
            {
                if (klasseToSet.length()==0)
                {
                    if (i==0)
                    {
                        // allow event to happen
                        mClassSetting--;
                        jComboBoxKlasse.setSelectedIndex(i);
                        mClassSetting++;
                        klasse = item;
                    }
                }
                else
                {
                    if (klasseToSet.equalsIgnoreCase(item))
                    {
                        // allow event to happen
                        mClassSetting--;
                        jComboBoxKlasse.setSelectedIndex(i);
                        mClassSetting++;
                        klasse = item;
                    }
                }
            }
            i++;
        }
        mClassSetting--;
        if ((select) && (klasse.length()==0))
        {
            if (jComboBoxKlasse.getItemCount()>0)
            {
                jComboBoxKlasse.setSelectedIndex(0);
                klasse = jComboBoxKlasse.getSelectedItem().toString();
            }
        }
        if (!select)  jComboBoxKlasse.setSelectedIndex(-1);


        resetTileList(tileToSet);
    }
    
    String getTileClass()
    {
        if (jComboBoxKlasse.getSelectedIndex()==-1) return "";
        String _class = jComboBoxKlasse.getSelectedItem().toString().trim();
        return _class;
    }
    TileDataPool getPool()
    {
        return mTileDataPool;
    }

    ImageSequenceData getImageSequenceDataForTile(TileData tileData)
    {
/*        
        if (tileData.mImageDataFile.trim().length()==0) return null;

        String imageFilename = "Graphics"+File.separator+tileData.mImageDataFile+".xml";
        ImageSequenceDataPool imagePool = new ImageSequenceDataPool(imageFilename);
        if (imagePool == null) return null;
        String nameToSet = tileData.getImageDataName();
        return imagePool.get(nameToSet);
*/        
        return null;
    }

    void resetTileList(String selectName)
    {
        mAllTilesInClass = new Vector <TileData>();

        String _class = getTileClass();
        TileDataPool pool = getPool();

        if (pool == null) return;

        Collection<TileData> colDk = pool.getMapForKlasse(_class).values();
        Iterator<TileData> iterDk = colDk.iterator();
        /** Sorting */  Vector<String> names = new Vector<String>();
        while (iterDk.hasNext())
        {
            TileData deck = iterDk.next();
            mAllTilesInClass.addElement(deck);
            names.addElement(deck.mName);

        }
        Collections.sort(names, new Comparator<String>() {@Override
                public int compare(String s1, String s2) { return s1.compareTo(s2); } });
        Collections.sort(mAllTilesInClass, new Comparator<TileData>() {@Override
            public int compare(TileData s1, TileData s2) { return s1.mName.compareTo(s2.mName); } });
        setAllTiles(selectName);
    }
     
    private void jPanelMouseTileClickedImageVertical(java.awt.event.MouseEvent evt) 
    {
        JComponent c = (JComponent) evt.getSource();
        c = (JComponent) c.getParent();
        JPanel newSelectedImagePanel = (JPanel) c;
        if (newSelectedImagePanel == currentSelectedTileImagePanel) return;

        if (currentSelectedTileImagePanel != null)
        {
            currentSelectedTileImagePanel.setBorder(javax.swing.BorderFactory.createLineBorder(new java.awt.Color(0, 0, 0)));
        }

        currentSelectedTileImagePanel = newSelectedImagePanel;

        currentSelectedTileImagePanel.setBorder(javax.swing.BorderFactory.createLineBorder(Color.ORANGE));
        String name  = currentSelectedTileImagePanel.getName();

        for (int t = 0; t < mAllTilesInClass.size(); t++)
        {
            TileData tileData = mAllTilesInClass.elementAt(t);
            if (tileData.mName.equals(name))
            {
                mCurrentTile = tileData;
                break;
            }
        }
    }     
    void setAllTiles(String selectName)
    {
        jPanelIMageCollection1.removeAll();
        currentSelectedTileImagePanel = null;

        int selected = 0;
        for (int t = 0; t < mAllTilesInClass.size(); t++)
        {
            TileData tileData = mAllTilesInClass.elementAt(t);
            if (tileData.mName.equals(selectName))
            {
                selected = t;
                break;
            }
        }
        int x = 5;
        int y = 5;
    
        for (int t = 0; t < mAllTilesInClass.size(); t++)
        {
            TileData tileData = mAllTilesInClass.elementAt(t);
            // jPanelIMageCollection1

            ImageSequenceData iSData = getImageSequenceDataForTile(tileData);
            String name = tileData.mName;

            JPanel ipanel = new JPanel();
            if (t==selected)
            {
                currentSelectedTileImagePanel = ipanel;
                ipanel.setBorder(javax.swing.BorderFactory.createLineBorder(Color.ORANGE));
                mCurrentTile = tileData;
                mClassSetting++;
                mClassSetting--;
            }
            else
                ipanel.setBorder(javax.swing.BorderFactory.createLineBorder(new java.awt.Color(0, 0, 0)));


            ipanel.setName(""+name);
            ipanel.setPreferredSize(new java.awt.Dimension(152,152));
            ipanel.setLayout(new BorderLayout());

            ImageComponent mip = new ImageComponent();
            ipanel.add(mip, BorderLayout.CENTER);


            mip.addMouseListener(new java.awt.event.MouseAdapter() {
                @Override
                public void mousePressed(java.awt.event.MouseEvent evt) {
                    notDragged = true;
                }
                public void mouseReleased(java.awt.event.MouseEvent evt) {
                    if (notDragged)
                        jPanelMouseTileClickedImageVertical(evt);
                }
            });
                /////////////////
            class MyTransferHandler extends TransferHandler
            {
                JPanel me;
                public MyTransferHandler(JPanel c)
                {
                    me = c;
                }
                public int getSourceActions(JComponent c)
                {
                    return TransferHandler.MOVE;
                }
                public  Transferable createTransferable(JComponent c)
                {
                    return new StringSelection(me.getName());
                }
                public void exportDone(JComponent source, Transferable data, int action)
                {

                }
            }

            mip.setTransferHandler(new MyTransferHandler(ipanel));
            mip.addMouseMotionListener(new MouseMotionListener(){
                @Override
                public void mouseDragged(MouseEvent e)
                {
                    notDragged = false;
                    e.consume();
                    JComponent c =(JComponent) e.getSource();
                    TransferHandler handler = c.getTransferHandler();
                    handler.exportAsDrag(c,e,TransferHandler.MOVE);
                    System.out.println("Draging?");
                }
                @Override public void mouseMoved(MouseEvent e) { }
            });

            ipanel.setBounds(x, y, 152, 152);
            jPanelIMageCollection1.add(ipanel);
            if (iSData != null)
            {
                Vector <BaseImageData> data = BaseImageData.toBase(iSData);
                if (data.size()>0)
                {
                    Vector<Image> images = new Vector<Image>();
                    for (int i = 0; i < data.size(); i++)
                    {
                        BaseImageData baseImageData = data.elementAt(i);
                        images.addElement(baseImageData.image);
                    }
                    mip.setSequence(new ImageSequence(iSData));
                    mip.setDelay(iSData.getDelay());
                }
            }

            y += 152;
            y += 5;
            mip.setScaled(true, 152, 152);
            mip.setVisible(true);
        }

        jPanelIMageCollection1.setBounds(0,0,62,y);
        jPanelIMageCollection1.setPreferredSize(new Dimension(62,y));
        jPanelIMageCollection1.invalidate();
        jPanelIMageCollection1.validate();
        jPanelIMageCollection1.repaint();


        repaint();
        // TODO
    }

    private void clearAll() /* allneeded*/
    {
        mClassSetting++;
        mCurrentTile = new TileData();
        jComboBoxKlasse.setSelectedIndex(-1);
        mClassSetting--;
    }

    private void jTextFieldTileFileFocusLost(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_jTextFieldTileFileFocusLost
        // if enabled, switching to another tab also loses focus
        //jTextFieldTileFileActionPerformed(null);
    }//GEN-LAST:event_jTextFieldTileFileFocusLost

    private void jButtonFileSelect1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButtonFileSelect1ActionPerformed
        InternalFrameFileChoser fc = new csa.gui.dialogs.InternalFrameFileChoser();
        fc.setCurrentDirectory(new java.io.File("xml"+File.separator+"Tile"));
        FileNameExtensionFilter  filter = new  FileNameExtensionFilter("xml", "xml");
        fc.setFileFilter(filter);
        int r = fc.showOpenDialog(Configuration.getConfiguration().getMainFrame());
        if (r != InternalFrameFileChoser.APPROVE_OPTION) return;
        String name = fc.getSelectedFile().getName();
        jTextFieldTileFile.setText(csa.util.UtilityString.replace(name, ".xml",""));
        jTextFieldTileFileActionPerformed(null);
    }//GEN-LAST:event_jButtonFileSelect1ActionPerformed

    private void jComboBoxKlasseActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jComboBoxKlasseActionPerformed
        if (mClassSetting >0 ) return;
        mClassSetting++;

        String selected = jComboBoxKlasse.getSelectedItem().toString();
        clearAll();

        resetConfigPool(true, selected, "");
        mClassSetting--;
    }//GEN-LAST:event_jComboBoxKlasseActionPerformed

    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JButton jButtonFileSelect1;
    private javax.swing.JComboBox jComboBoxKlasse;
    private javax.swing.JLabel jLabel4;
    private javax.swing.JLabel jLabel5;
    private javax.swing.JPanel jPanel1;
    private javax.swing.JPanel jPanel16;
    private javax.swing.JPanel jPanel17;
    private javax.swing.JPanel jPanelIMageCollection1;
    private javax.swing.JScrollPane jScrollPane9;
    private javax.swing.JTextField jTextFieldTileFile;
    // End of variables declaration//GEN-END:variables


}
