package cytoscape.dialogs.preferences;


import cytoscape.bookmarks.Bookmarks;
import cytoscape.bookmarks.DataSource;
import cytoscape.util.BookmarksUtil;
import cytoscape.util.URLUtil;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.net.MalformedURLException;
import java.net.URL;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JTextField;
import javax.swing.WindowConstants;


/**
 * @author ruschein
 */
public class EditBookmarkDialog extends JDialog {
	private JButton cancelButton;
	private JLabel categoryLabel;
	private JLabel jLabel1;
	private JLabel jLabel3;
	private JLabel jLabel4;
	private JTextField nameTextField;
	private JButton okButton;
	private JTextField urlTextField;

	private final JDialog parent;
	private final Bookmarks bookmarks;
	private final String categoryName;
	private final String mode;
	private DataSource dataSource;

	/** Creates new form EditBookmarkDialog */
	public EditBookmarkDialog(final JDialog parent, final boolean modal, final Bookmarks bookmarks,
                                  final String categoryName, final String mode, final DataSource dataSource)
	{
		super(parent, modal);

		this.parent = parent;
		this.bookmarks = bookmarks;
		this.categoryName = categoryName;
		this.mode = mode;
		this.dataSource = dataSource;

		initComponents();
		categoryLabel.setText(categoryName);

		if (mode.equalsIgnoreCase("new"))
			setTitle("Add New Bookmark");
		else {
			setTitle("Edit Bookmark");
			nameTextField.setText(dataSource.getName());
			urlTextField.setText(dataSource.getHref());
		}
	}

	public DataSource getDataSource(){
		return dataSource;
	}

	/** 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")
		private void initComponents() {

		jLabel1 = new JLabel();
		categoryLabel = new JLabel();
		jLabel3 = new JLabel();
		jLabel4 = new JLabel();
		nameTextField = new JTextField();
		urlTextField = new JTextField();
		okButton = new JButton();
		cancelButton = new JButton();

		setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
		setTitle("Edit Bookmark");

		jLabel1.setText("Category:");

		categoryLabel.setText("******************");

		jLabel3.setText("Name:");

		jLabel4.setText("URL:");

		okButton.setText("Ok");
		okButton.setSelected(true);
		okButton.addActionListener(new ActionListener() {
				public void actionPerformed(final ActionEvent evt) {
					if (mode.equalsIgnoreCase("new"))
						okButtonNewActionPerformed(evt);
					else
						okButtonEditActionPerformed(evt);
				}
			});

		cancelButton.setText("Cancel");
		cancelButton.addActionListener(new ActionListener() {
				public void actionPerformed(final ActionEvent evt) {
					cancelButtonActionPerformed(evt);
				}
			});

		org.jdesktop.layout.GroupLayout layout = new org.jdesktop.layout.GroupLayout(getContentPane());
		getContentPane().setLayout(layout);
		layout.setHorizontalGroup(
					  layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
					  .add(layout.createSequentialGroup()
					       .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING, false)
						    .add(layout.createSequentialGroup()
							 .add(32, 32, 32)
							 .add(jLabel1)
							 .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED))
						    .add(org.jdesktop.layout.GroupLayout.TRAILING, layout.createSequentialGroup()
							 .addContainerGap(42, Short.MAX_VALUE)
							 .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.TRAILING)
							      .add(jLabel4)
							      .add(jLabel3))
							 .add(20, 20, 20)))
					       .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
						    .add(categoryLabel, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 112, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
						    .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.TRAILING, false)
							 .add(org.jdesktop.layout.GroupLayout.LEADING, urlTextField)
							 .add(org.jdesktop.layout.GroupLayout.LEADING, nameTextField, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 608, Short.MAX_VALUE)
							 .add(layout.createSequentialGroup()
							      .add(441, 441, 441)
							      .add(okButton)
							      .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
							      .add(cancelButton))))
					       .addContainerGap())
					  );
		layout.setVerticalGroup(
					layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
					.add(layout.createSequentialGroup()
					     .add(22, 22, 22)
					     .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE)
						  .add(jLabel1, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 16, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
						  .add(categoryLabel))
					     .addPreferredGap(org.jdesktop.layout.LayoutStyle.UNRELATED)
					     .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE)
						  .add(nameTextField, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
						  .add(jLabel3))
					     .add(28, 28, 28)
					     .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE)
						  .add(jLabel4)
						  .add(urlTextField, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))
					     .add(18, 18, 18)
					     .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE)
						  .add(cancelButton)
						  .add(okButton))
					     .addContainerGap(org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
					);

		pack();
	}

	private void okButtonNewActionPerformed(final ActionEvent evt) {
		final String name = nameTextField.getText().trim();
		final String urlCandidate = urlTextField.getText().trim();

		if (name.equals("") || urlCandidate.equals("")) {
			JOptionPane.showMessageDialog(parent, "Please provide a name and URL!", "Warning",
						      JOptionPane.INFORMATION_MESSAGE);
			return;
		}

		final URL url;
		if (URLUtil.isValid(urlCandidate)) {
			try {
				url = new URL(urlCandidate);
			} catch (final MalformedURLException e) {
				throw new IllegalStateException("We should never get here!");
			}
		} else {
			JOptionPane.showMessageDialog(parent, "Invalid URL!", "Warning",
						      JOptionPane.INFORMATION_MESSAGE);
			return;
		}
				
		final DataSource theDataSource = new DataSource();
		theDataSource.setName(name);
		theDataSource.setHref(urlCandidate);

		
		if (BookmarksUtil.isInBookmarks(url, categoryName, theDataSource)) {
			JOptionPane.showMessageDialog(parent, "Duplicate bookmark!", "Warning",
						      JOptionPane.INFORMATION_MESSAGE);

			return;
		}

		BookmarksUtil.saveBookmark(bookmarks, categoryName, theDataSource);
		dataSource = theDataSource;

		dispose();
	}

	private void okButtonEditActionPerformed(final ActionEvent evt) {
		final String name = nameTextField.getText().trim();
		final String url = urlTextField.getText().trim();

		if (name.equals("") || url.equals("")) {
			JOptionPane.showMessageDialog(parent, "Please provide a name and URL!", "Warning",
						      JOptionPane.INFORMATION_MESSAGE);
			return;
		}

		if (!URLUtil.isValid(url)){
			JOptionPane.showMessageDialog(parent, "Invalid URL!", "Warning",
						      JOptionPane.INFORMATION_MESSAGE);
			return;
		}
				
		// There is no change, do nothing
		if (dataSource.getName().equalsIgnoreCase(name) && this.dataSource.getHref().equalsIgnoreCase(url)){
			dispose();
			return;
		}
				
		if (!URLUtil.isValid(url)){
			JOptionPane.showMessageDialog(parent, "Invalid URL", "Warning",
						      JOptionPane.INFORMATION_MESSAGE);
			return;
		}
				
		if (!name.equalsIgnoreCase(dataSource.getName())) {
			// The bookmark name has been changed
			DataSource newDataSource = new DataSource();
			newDataSource.setName(name);
			newDataSource.setHref(url);

			if (BookmarksUtil.isInBookmarks(bookmarks, categoryName, newDataSource)){
				// The bookmark name must be unique
				JOptionPane.showMessageDialog(parent, "Bookmark with this name already existed!", "Warning",
							      JOptionPane.INFORMATION_MESSAGE);
				return;
			}
					
			// first delete the old one, then add (note: name is key of DataSource)
			BookmarksUtil.deleteBookmark(bookmarks, categoryName, dataSource);
			BookmarksUtil.saveBookmark(bookmarks, categoryName, newDataSource);
		}
		else { // The bookmark name has not been changed		
			// first delete the old one, then add (note: name is key of DataSource)
			BookmarksUtil.deleteBookmark(bookmarks, categoryName, dataSource);
					
			dataSource.setHref(url);
			BookmarksUtil.saveBookmark(bookmarks, categoryName, dataSource);						
		}

		dispose();
	}

	private void cancelButtonActionPerformed(final ActionEvent evt) {
		dispose();
	}
}
