/* Copyright Dassault Systemes, 1999, 2009 */


package examples.development.datatypes;

import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;

import javax.swing.JLabel;
import javax.swing.JTextField;

import com.engineous.common.i18n.IString;
import com.engineous.sdk.exception.SDKException;
import com.engineous.sdk.gui.ExceptionHandler;
import com.engineous.sdk.resmgr.ResMgr;
import com.engineous.sdk.vars.AbstractDataHandlerEditor;
import com.engineous.sdk.vars.DataHandler;
import com.engineous.sdk.vars.FileUtil;
import com.engineous.sdk.vars.FileValueType;
import com.engineous.sdk.vars.Variable;
import com.engineous.sdk.vars.VariableException;

/**
 * Editor for the Example URL Data Handler.
 * This is a trivial editor that is displayed on the Design Gateway files tab,
 * in the Source panel of an Input file parameter or the Destination panel for an output file parameter.
 */
public class DataHandlerURLEditor
		extends AbstractDataHandlerEditor {

	transient private static final Class CLASS = DataHandlerURLEditor.class;

	// Swing components that make up the editor panel.
	private GridBagLayout gridBagLayout1 = new GridBagLayout();
	private JLabel eLabel1 = new JLabel();
	private JTextField textURL = new JTextField();

	// The Data Handler that this editor is editing.  This handler is directly updated by any changes.
	private DataHandlerURL handler;

	/**
	 * Constructs a DataHandlerURLEditor
	 */
	public DataHandlerURLEditor() {

		// Lay out the GUI.
		jbInit();
	}

	/**
	 * Called by the framework to inform the editor of the object it is editing.
	 * @param fileValue The FileValue that owns this handler.
	 * @param dh The handler object to be edited.  Must be a DataHandlerURL for this class.
	 * @param var The Variable that owns the FileValue.  May be null, so be careful.
	 * @throws SDKException
	 */
	public void setDataHandler(FileValueType fileValue, DataHandler dh, Variable var)
			throws SDKException {

		if (!(dh instanceof DataHandlerURL)) {    // Sanity check
			handler = null;
			throw new SDKException(new IString(CLASS, 30706, "Handler is not of expected type (DataHandlerURL)."));
		}
		handler = (DataHandlerURL)dh;

		// Save the file value in the member of AbstractDataHandlerEditor in case someone needs it.
		this.fileValue = fileValue;

		// Update UI with handler configuration
		// In this case, the URL handler implements getResourceName to return its entire configuration
		// (the raw URL), so use that.  Other editors would have to use specific methods of the handler class
		// to extract individual pieces of the configuration.
		textURL.setText(handler.getResourceName());

		configChanged = false;    // Reset change flag
	}

	/**
	 * Update the handler from the current UI state.
	 */
	void updateHandler() {

		if (handler == null) {
			return;
		}

		try {
			// Update handler with new URL          
			String priorResourceName = handler.getResourceName();
			handler.setResourceName(textURL.getText().trim());

			// If this is the first time the handler was configured, make a guess
			// as to the file type and encoding.
			if (priorResourceName == null) {
				if (fileValue != null) {
					fileValue.setDataType(FileUtil.guessFileType(fileValue));
					// Note for file handlers we leave the encoding as 'automatic'
					// so it will be determined at runtime.
				}
			}

			// Inform AbstractDataHandler that the configuration has been changed.
			configChanged = true;
		}
		catch (VariableException ex) {
			// This should not happen, as guessFileType only returns valid data types.
			// If it does happen, let everyone know.  ExceptionHandler logs the message (3rd argument)
			// and displays it to the user.  ExceptionHandler should only be called from classes that
			// are part of a graphical user interface - do not call it from runtime classes or
			// utility classes.
			ExceptionHandler.showError(this, ex, new IString(CLASS, -1, "Error configuring URL Data Handler: {0}", ex.getMessage()),
					new IString(CLASS, -1, "Error in URL Data Handler"));
		}

	}

	/**
	 * Construct the user interface and register needed listeners.
	 */
	private void jbInit() {

		eLabel1.setText(ResMgr.getMessage(CLASS, 88725, "URL"));
		this.setLayout(gridBagLayout1);

		this.add(eLabel1,
				 new GridBagConstraints(0, 0, 1, 1, 0.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.NONE, new Insets(5, 5, 5, 0), 0, 0));
		this.add(textURL,
				 new GridBagConstraints(1, 0, 1, 1, 1.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, new Insets(5, 5, 5, 5), 0,
					 0));

		// Listener that updates the handler on focus loss or action event (ENTER)
		//=========================================================================
		/**
		 * Title:        class <br>
		 * Description:  $defaultDesc$<br>
		 * Copyright:    $copyright$<br>
		 * Company:      $company$<br>
		 * @author $author$
		 */
		//=========================================================================
		final class Listener
				implements FocusListener, ActionListener {

			/**
			 * Method focusGained
			 * @param arg0
			 */
			public void focusGained(FocusEvent arg0) {}

			/**
			 * Method focusLost
			 * @param arg0
			 */
			public void focusLost(FocusEvent arg0) {
				updateHandler();
			}

			/**
			 * Method actionPerformed
			 * @param arg0
			 */
			public void actionPerformed(ActionEvent arg0) {
				updateHandler();
			}
		}
		Listener updateListener = new Listener();

		textURL.addFocusListener(updateListener);
		textURL.addActionListener(updateListener);
	}

	/**
	 * Is the DATA pointed to by this handler editable?
	 * This should return true only if it is OK to attempt to re-write the data at DESIGN time after
	 * the user edits the file from the "Preview" panel.
	 * <p>
	 * This method returns true only for a File Handler or an In-Model handler.
	 * @return boolean false for a URL handler.
	 */
	public boolean isContentEditable() {
		return false;
	}

	/**
	 * Inform the editor that it is used at runtime to display information about an output file,
	 * or in some other context where editing the configuration is not allowed.
	 * This should prevent the user from editing the configuration, but not alter how it is displayed.
	 * Note: if this method is never called, assume the editor can be used to edit.
	 * @param viewOnly true if this editor is for display only, false if it is truely for editing.
	 */
	public void setViewOnly(boolean viewOnly) {

		textURL.setEditable(!viewOnly);
	}


}

