
package jp.riken.brain.ni.samuraigraph.base;

import java.awt.Color;
import java.awt.Dialog;
import java.awt.Frame;
import java.awt.GraphicsConfiguration;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
import java.net.URL;
import java.util.ArrayList;
import java.util.Locale;
import java.util.ResourceBundle;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JColorChooser;
import javax.swing.JComponent;
import javax.swing.SpinnerNumberModel;
import javax.swing.border.Border;
import javax.swing.border.LineBorder;
import javax.swing.border.MatteBorder;
import javax.swing.colorchooser.ColorSelectionModel;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;


/**
 * プロパティ設定用ダイアログ
 */
public abstract class SGPropertyDialog extends SGDialog implements ChangeListener
{

	/**
	 *
	 */
//	protected JButton mOKButton = new JButton("OK");


	/**
	 *
	 */
//	protected JButton mCancelButton = new JButton("Cancel");


	/**
	 *
	 */
//	protected JButton mPreviewButton = new JButton("Preview");


	/**
	 * 
	 */
//	protected JPanel mButtonPanel = new JPanel();



	/**
	 * List of the property setting listeners.
	 */
	protected ArrayList mPropertySettingListenerList = new ArrayList();



	/**
	 * 
	 */
	public SGPropertyDialog()
	{
		super();
		this.initialize();
	}


	/**
	 * 
	 */
	public SGPropertyDialog( Dialog owner )
	{
		super( owner );
		this.initialize();
	}


	/**
	 * 
	 */
	public SGPropertyDialog( Dialog owner, boolean modal )
	{
		super( owner, modal );
		this.initialize();
	}


	/**
	 * 
	 */
	public SGPropertyDialog( Dialog owner, String title )
	{
		super( owner, title );
		this.initialize();
	}


	/**
	 * 
	 */
	public SGPropertyDialog( Dialog owner, String title, boolean modal )
	{
		super( owner, title, modal );
		this.initialize();
	}


	/**
	 * 
	 */
	public SGPropertyDialog( Dialog owner, String title, boolean modal, GraphicsConfiguration gc )
	{
		super( owner, title, modal, gc );
		this.initialize();
	}



	/**
	 * 
	 */
	public SGPropertyDialog( Frame owner )
	{
		super( owner );
		this.initialize();
	}


	/**
	 * 
	 */
	public SGPropertyDialog( Frame owner, boolean modal )
	{
		super( owner, modal );
		this.initialize();
	}


	/**
	 * 
	 */
	public SGPropertyDialog( Frame owner, String title )
	{
		super( owner, title );
		this.initialize();
	}


	/**
	 * 
	 */
	public SGPropertyDialog( Frame owner, String title, boolean modal )
	{
		super( owner, title, modal );
		this.initialize();
	}


	/**
	 * 
	 */
	public SGPropertyDialog( Frame owner, String title, boolean modal, GraphicsConfiguration gc )
	{
		super( owner, title, modal, gc );
		this.initialize();
	}



	/**
	 * 
	 */
	private Icon mColorSelectionButtonEmphasisIcon = null;



	/**
	 * 
	 */
	private boolean initialize()
	{

		// create a color dialog
		this.mColorDialog = new SGColorDialog(
			this, "Color Dialog", false );
		this.mColorDialog.pack();
		this.mColorDialog.setResizable(false);

		// set this as a ChangeListener of the color selection model
		JColorChooser cc = this.mColorDialog.getColorChooser();
		ColorSelectionModel cModel = cc.getSelectionModel();
		cModel.addChangeListener(this);

		// create background icon for the button
		this.mColorSelectionButtonEmphasisIcon
			= this.createIcon(SGIConstants.RESOURCES_DIRNAME+"Lines.gif");


		return true;

	}



	/**
	 * name : name of resource file
	 */
	private ImageIcon createIcon( final String name )
	{
		if( name==null )
		{
			return null;
		}

		Class inClass = getClass();
		URL url = inClass.getResource(name);

//System.out.println("URL:"+url);

		ImageIcon icon;
		if( url!=null )
		{
			icon = new ImageIcon(url);
		}
		else
		{
			icon = new ImageIcon(name);
		}

//System.out.println("icon:"+icon);		
//System.out.println();

		return icon;
	}
	


	/**
	 * 
	 */
	protected String getString( final String key )
	{
		ResourceBundle bundle = ResourceBundle.getBundle("res",Locale.JAPAN);
//		ResourceBundle bundle = ResourceBundle.getBundle("res",Locale.ENGLISH);
		String val = bundle.getString(key);

		return val;
	}




	/**
	 * 
	 */
	public boolean setActionListener( final ActionListener listener )
	{
		return true;
	}


	/**
	 * 
	 */
	public boolean removeActionListener()
	{
		return true;
	}



	/**
	 * 
	 */
	protected SGColorDialog mColorDialog = null;


	/**
	 * 
	 */
	protected JButton mFocusedColorSetButton = null;


	/**
	 * 
	 */
	public SGColorDialog getColorDialog()
	{
		return this.mColorDialog;
	}


	/**
	 * 
	 */
	public void stateChanged( final ChangeEvent e )
	{

		Object source = e.getSource();

		if( this.mFocusedColorSetButton!=null
			&& ( source instanceof ColorSelectionModel ) )
		{
			Color cl = this.mColorDialog.getColorChooser().getColor();
			this.mFocusedColorSetButton.setBackground( cl );
			this.mColorDialog.getColorChooser().getSelectionModel().setSelectedColor( null );
		}

	}


	/**
	 * 
	 */
	public void setVisible( final boolean b )
	{
		super.setVisible(b);

		if( !b )
		{
			this.mColorDialog.setVisible(false);
		}
	}


	/**
	 * 
	 */
	public abstract ArrayList getColorSelectionComponentList();


	/**
	 * 
	 */
	public abstract ArrayList getActiveComponentList();


	/**
	 * 
	 */
	public abstract ArrayList getSpinnerList();


	/**
	 * 
	 */
	protected ArrayList getActiveComponentListFromSpinners()
	{
		final ArrayList list = new ArrayList();

		final ArrayList sList = this.getSpinnerList();
		for( int ii=0; ii<sList.size(); ii++ )
		{
			SGSpinner spinner = (SGSpinner)sList.get(ii);
			list.add( spinner.getFormattedTextField() );
		}

		return list;
	}



	/**
	 * 
	 */
	public boolean setColorButtonBorder( final JButton btn, final boolean flag )
	{

		ArrayList list = this.getColorSelectionComponentList();
		for( int ii=0; ii<list.size(); ii++ )
		{
			JComponent com = (JComponent)list.get(ii);
			if( com.equals(btn) && flag )
			{
				// ボタンを斜線で囲む
				Border border = new MatteBorder(this.mColorSelectionButtonEmphasisIcon);
				btn.setBorder(border);
			}
			else
			{
				com.setBorder( new LineBorder( Color.BLACK, 1 ) );
			}
		}

		return true;
	}


	/**
	 * 
	 */
	public boolean setColorButtonBorder( final boolean flag )
	{
		this.setColorButtonBorder( this.mFocusedColorSetButton, flag );

		return true;
	}


	/**
	 * 
	 */
	public void actionPerformed( final ActionEvent e )
	{
		Object source = e.getSource();
		String command = e.getActionCommand();

//System.out.println(source);

		if( this.getColorSelectionComponentList().contains(source) )
		{
			JButton btn = (JButton)source;

			// 属性に設定
			this.mFocusedColorSetButton = btn;

			// ボタンに装飾を施す
			this.setColorButtonBorder( true );

			// 色選択ダイアログを出す
			this.mColorDialog.setVisible(true);
		}


		ArrayList comList = this.getActiveComponentList();
		if( command.equals("OK") || comList.contains(source) )
		{
			this.onOK();
		}
		else if( command.equals("Cancel") )
		{
			this.onCanceled();
		}
		else if( command.equals("Preview") )
		{
			this.onPreviewed();
		}

	}



	public static final double LINE_WIDTH_MIN_VALUE = 0.25;
	public static final double LINE_WIDTH_MAX_VALUE = 6.0;
	public static final double LINE_WIDTH_STEP_SIZE = 0.25;

	public static final double FONT_SIZE_MIN_VALUE = 8.0;
	public static final double FONT_SIZE_MAX_VALUE = 96.0;
	public static final double FONT_SIZE_STEP_VALUE = 1.0;


	/**
	 * 
	 */
	public SpinnerNumberModel getLineWidthSpinnerNumberModel()
	{
		return new SpinnerNumberModel(
			LINE_WIDTH_MIN_VALUE,
			LINE_WIDTH_MIN_VALUE,
			LINE_WIDTH_MAX_VALUE,
			LINE_WIDTH_STEP_SIZE
		);
	}


	/**
	 * 
	 */
	public SpinnerNumberModel getFontSizeSpinnerNumberModel()
	{
		return new SpinnerNumberModel(
			FONT_SIZE_MIN_VALUE,
			FONT_SIZE_MIN_VALUE,
			FONT_SIZE_MAX_VALUE,
			FONT_SIZE_STEP_VALUE
		);
	}



	/**
	 * 
	 * @param l
	 * @return
	 */
	public boolean addPropertySettingListener(
		final SGIPropertySettingListener l )
	{
		this.mPropertySettingListenerList.add(l);
		return true;
	}


	/**
	 * 
	 * @param l
	 * @return
	 */
	public boolean removePropertySettingListener(
		final SGIPropertySettingListener l )
	{
		return this.mPropertySettingListenerList.remove(l);
	}



	/**
	 * 
	 * @param l
	 * @return
	 */
	public boolean removeAllPropertySettingListeners()
	{
		this.mPropertySettingListenerList.clear();
		return true;
	}



	/**
	 * 
	 * @return
	 */
	public boolean removeAllWindowListener()
	{
		WindowListener[] array = this.getWindowListeners();
		for( int ii=0; ii<array.length; ii++ )
		{
			this.removeWindowListener(array[ii]);
		}
		return true;
	}



	/**
	 * 
	 * @return
	 */
	protected boolean onOK()
	{
		if( this.commit()==false )
		{
			return false;
		}

		this.setCloseOption( OK_OPTION );

		this.removeAllPropertySettingListeners();
		this.setVisible(false);
		this.clearAllSpinners();

		return true;
	}



	/**
	 * 
	 * @return
	 */
	protected boolean onCanceled()
	{
		if( this.cancel() == false )
		{
			return false;
		}

		this.setCloseOption( CANCEL_OPTION );
		
		this.removeAllPropertySettingListeners();
		this.setVisible(false);
		this.clearAllSpinners();

		return true;
	}



	/**
	 * 
	 * @return
	 */
	protected boolean onPreviewed()
	{
		if( this.preview()==false )
		{
			return false;
		}
		return true;
	}



	/**
	 * 
	 *
	 */
	protected void clearAllSpinners()
	{
		ArrayList list = this.getSpinnerList();
		for( int ii=0; ii<list.size(); ii++ )
		{
			SGSpinner sp = (SGSpinner)list.get(ii);
			sp.clearTemporaryValues();
		}
	}
	
	
	/**
	 * 
	 * @return
	 */
	public boolean commit()
	{
		for( int ii=0; ii<this.mPropertySettingListenerList.size(); ii++ )
		{
			SGIPropertySettingListener l
				= (SGIPropertySettingListener)this.mPropertySettingListenerList.get(ii);
			if( l.commit() == false )
			{
				return false;
			}
		}

		this.setVisible(false);

		return true;
	}



	/**
	 * 
	 * @return
	 */
	public boolean cancel()
	{
//System.out.println("<< onCanceled >>");
		for( int ii=0; ii<this.mPropertySettingListenerList.size(); ii++ )
		{
//System.out.println("ii="+ii);
			SGIPropertySettingListener l
				= (SGIPropertySettingListener)this.mPropertySettingListenerList.get(ii);
			if( l.cancel() == false )
			{
//System.out.println("false");
				return false;
			}
		}
//System.out.println();

		return true;
	}


	/**
	 * 
	 * @return
	 */
	protected boolean preview()
	{
		for( int ii=0; ii<this.mPropertySettingListenerList.size(); ii++ )
		{
			SGIPropertySettingListener l
				= (SGIPropertySettingListener)this.mPropertySettingListenerList.get(ii);
			if( l.preview() == false )
			{
				return false;
			}
		}
		return true;
	}


	/**
	 * 
	 * @return
	 */
	public boolean setDialogProperty()
	{
		return true;
	}


	/**
	 * 
	 */
	public void windowClosing(final WindowEvent e)
	{
		super.windowClosing(e);
		this.onCanceled();
	}


}

