package cytoscape.visual.customgraphic.ui;

import java.awt.Image;
import java.util.Collection;

import javax.swing.JPanel;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;

import org.jdesktop.swingx.JXImageView;

import cytoscape.Cytoscape;
import cytoscape.visual.customgraphic.CyCustomGraphics;
import cytoscape.visual.customgraphic.Taggable;
import cytoscape.visual.customgraphic.impl.bitmap.URLImageCustomGraphics;

/**
 * 
 * @author kono
 */
public class CustomGraphicsDetailPanel extends JPanel implements
		ListSelectionListener {

	private static final long serialVersionUID = -412539582192509545L;

	private static final String TAG_DELIMITER = ",";
	
	private CyCustomGraphics cg;

	/** Creates new form CustomGraphicsDetailPanel */
	public CustomGraphicsDetailPanel() {
		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">
	private void initComponents() {
		infoPanel = new javax.swing.JPanel();
        nameLabel = new javax.swing.JLabel();
        tagLabel = new javax.swing.JLabel();
        nameTextField = new javax.swing.JTextField();
        tagTextField = new javax.swing.JTextField();
        imageViewPanel = new JXImageView();
        modifyPanel = new javax.swing.JPanel();
        widthLabel = new javax.swing.JLabel();
        widthTextField = new javax.swing.JTextField();
        heightLabel = new javax.swing.JLabel();
        lockCheckBox = new javax.swing.JCheckBox();
        heightTextField = new javax.swing.JTextField();
        resetButton = new javax.swing.JButton();
        searchButton = new javax.swing.JButton();

        infoPanel.setBorder(javax.swing.BorderFactory.createEtchedBorder());

        nameLabel.setText("Name:");

        tagLabel.setText("Tags:");

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

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

        org.jdesktop.layout.GroupLayout infoPanelLayout = new org.jdesktop.layout.GroupLayout(infoPanel);
        infoPanel.setLayout(infoPanelLayout);
        infoPanelLayout.setHorizontalGroup(
            infoPanelLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(infoPanelLayout.createSequentialGroup()
                .addContainerGap()
                .add(infoPanelLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
                    .add(tagLabel)
                    .add(nameLabel))
                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                .add(infoPanelLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
                    .add(nameTextField, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 491, Short.MAX_VALUE)
                    .add(tagTextField, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 491, Short.MAX_VALUE))
                .addContainerGap())
        );
        infoPanelLayout.setVerticalGroup(
            infoPanelLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(infoPanelLayout.createSequentialGroup()
                .addContainerGap()
                .add(infoPanelLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE)
                    .add(nameLabel)
                    .add(nameTextField, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                .add(infoPanelLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE)
                    .add(tagLabel)
                    .add(tagTextField, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))
                .addContainerGap(org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );

        imageViewPanel.setBorder(javax.swing.BorderFactory.createTitledBorder("Actual Size View"));

        org.jdesktop.layout.GroupLayout imageViewPanelLayout = new org.jdesktop.layout.GroupLayout(imageViewPanel);
        imageViewPanel.setLayout(imageViewPanelLayout);
        imageViewPanelLayout.setHorizontalGroup(
            imageViewPanelLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(0, 573, Short.MAX_VALUE)
        );
        imageViewPanelLayout.setVerticalGroup(
            imageViewPanelLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(0, 228, Short.MAX_VALUE)
        );

        modifyPanel.setBorder(javax.swing.BorderFactory.createEtchedBorder());

        widthLabel.setText("Width:");

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

        heightLabel.setText("Height:");

        lockCheckBox.setSelected(true);
        lockCheckBox.setText("Aspect Ratio");
        lockCheckBox.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                //lockCheckBoxActionPerformed(evt);
            }
        });

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

        resetButton.setText("Original");
        resetButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                resetButtonActionPerformed(evt);
            }
        });

        searchButton.setText("Search");
        searchButton.setToolTipText("This function is not implemented yet.");
        searchButton.setEnabled(false);
        searchButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                optionButtonActionPerformed(evt);
            }
        });

        org.jdesktop.layout.GroupLayout modifyPanelLayout = new org.jdesktop.layout.GroupLayout(modifyPanel);
        modifyPanel.setLayout(modifyPanelLayout);
        modifyPanelLayout.setHorizontalGroup(
            modifyPanelLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(modifyPanelLayout.createSequentialGroup()
                .addContainerGap()
                .add(widthLabel)
                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                .add(widthTextField, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 60, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                .add(heightLabel)
                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                .add(heightTextField, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 60, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                .add(lockCheckBox)
                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                .add(resetButton)
                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                .add(searchButton)
                .add(8, 8, 8))
        );
        modifyPanelLayout.setVerticalGroup(
            modifyPanelLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(modifyPanelLayout.createSequentialGroup()
                .addContainerGap()
                .add(modifyPanelLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE)
                    .add(widthLabel)
                    .add(widthTextField, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
                    .add(heightLabel)
                    .add(heightTextField, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
                    .add(lockCheckBox)
                    .add(resetButton)
                    .add(searchButton))
                .addContainerGap(org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );

        org.jdesktop.layout.GroupLayout layout = new org.jdesktop.layout.GroupLayout(this);
        this.setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(infoPanel, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
            .add(org.jdesktop.layout.GroupLayout.TRAILING, modifyPanel, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
            .add(imageViewPanel, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(layout.createSequentialGroup()
                .add(infoPanel, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                .add(imageViewPanel, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                .add(modifyPanel, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))
        );
	}// </editor-fold>

	private void nameTextFieldActionPerformed(java.awt.event.ActionEvent evt) {
		final String newName = this.nameTextField.getText();
		if (newName != null && newName.trim().length() != 0 && cg != null)
			cg.setDisplayName(this.nameTextField.getText());
	}
	

	private void resetButtonActionPerformed(java.awt.event.ActionEvent evt) {
		if (cg == null || cg.getRenderedImage() == null)
			return;

		if (cg instanceof URLImageCustomGraphics) {
			final Image image = ((URLImageCustomGraphics) cg).resetImage();
			imageViewPanel.setImage(image);
			final int w = image.getWidth(null);
			final int h = image.getHeight(null);
			widthTextField.setText(Integer.toString(w));
			heightTextField.setText(Integer.toString(h));
			cg.setWidth(w);
			cg.setHeight(h);
			Cytoscape.getCurrentNetworkView().redrawGraph(false, true);
		}
	}

	private void widthTextFieldActionPerformed(java.awt.event.ActionEvent evt) {
		resizeImage(true);
	}

	private void heightTextFieldActionPerformed(java.awt.event.ActionEvent evt) {
		resizeImage(false);
	}

	private void resizeImage(boolean isWidth) {
		final String width = widthTextField.getText();
		final String height = heightTextField.getText();


		final Image currentImage = cg.getRenderedImage();
		if (currentImage == null)
			return;

		final boolean lock = this.lockCheckBox.isSelected();

		final int currentW = currentImage.getWidth(null);
		final int currentH = currentImage.getHeight(null);

		Integer w;
		Integer h;
		try {
			w = Integer.parseInt(width);
			h = Integer.parseInt(height);
		} catch (NumberFormatException e) {
			// back to current size
			this.widthTextField.setText(Integer.toString(currentW));
			this.heightTextField.setText(Integer.toString(currentH));
			return;
		}

		float ratio;
		int converted;
		if (lock == false) {
			cg.setWidth(w);
			cg.setHeight(h);
			imageViewPanel.setImage(cg.getRenderedImage());
		} else if (isWidth) {
			ratio = ((float) currentH) / ((float) currentW);
			converted = (int) (w * ratio);
			cg.setWidth(w);
			cg.setHeight(converted);
			imageViewPanel.setImage(cg.getRenderedImage());
			heightTextField.setText(Integer.toString(converted));
		} else {
			ratio = ((float) currentW) / ((float) currentH);
			converted = (int) (h * ratio);
			cg.setWidth(converted);
			cg.setHeight(h);
			imageViewPanel.setImage(cg.getRenderedImage());
			widthTextField.setText(Integer.toString(converted));
		}
		Cytoscape.getCurrentNetworkView().redrawGraph(false, true);
	}

	private void tagsTextFieldActionPerformed(java.awt.event.ActionEvent evt) {
		final String tagStr = this.tagTextField.getText();
		if(tagStr != null && tagStr.trim().length() != 0) {
			if(cg instanceof Taggable) {
				final String[] tags = tagStr.split(TAG_DELIMITER);
				for(String tag:tags)
					((Taggable) cg).getTags().add(tag.trim());
			}			
		}
	}
	
	private void optionButtonActionPerformed(java.awt.event.ActionEvent evt) {
    }
	
	

	// Variables declaration - do not modify
	private javax.swing.JLabel heightLabel;
	private javax.swing.JTextField heightTextField;
	private JXImageView imageViewPanel;
	private javax.swing.JPanel infoPanel;
	private javax.swing.JCheckBox lockCheckBox;
	private javax.swing.JPanel modifyPanel;
	private javax.swing.JLabel nameLabel;
	private javax.swing.JTextField nameTextField;
	private javax.swing.JButton resetButton;
	private javax.swing.JLabel tagLabel;
	private javax.swing.JTextField tagTextField;
	private javax.swing.JLabel widthLabel;
	private javax.swing.JTextField widthTextField;
    private javax.swing.JButton searchButton;


	// End of variables declaration

	public void valueChanged(ListSelectionEvent e) {

		if (!(e.getSource() instanceof CustomGraphicsBrowser)
				|| e.getValueIsAdjusting())
			return;

		final CustomGraphicsBrowser browser = (CustomGraphicsBrowser) e
				.getSource();

		cg = (CyCustomGraphics) browser.getSelectedValue();
		if(cg == null) {
			imageViewPanel.setImage((Image)null);
			heightTextField.setText(null);
			widthTextField.setText(null);
			nameTextField.setText(null);
			nameTextField.setToolTipText(null);
			tagTextField.setText(null);
			return;
		}
			
		final Image img = cg.getRenderedImage();

		// Set up detail panel
		imageViewPanel.setImage(img);
		heightTextField.setText(Integer.toString(img.getHeight(null)));
		widthTextField.setText(Integer.toString(img.getWidth(null)));
		nameTextField.setText(cg.getDisplayName());
		nameTextField.setToolTipText(cg.getDisplayName());
		if(cg instanceof Taggable) {
			final Collection<String> tags = ((Taggable) cg).getTags();
			final int tagCount = tags.size();
			int counter = 0;
			final StringBuilder tagBuilder = new StringBuilder();
			for(String tag: tags) {
				tagBuilder.append(tag);
				counter++;
				if(tagCount != counter)
					tagBuilder.append(", ");
			}
			tagTextField.setText(tagBuilder.toString());
			tagTextField.setToolTipText(tagBuilder.toString());
		}
	}

}
