package com.test;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.geom.Rectangle2D;
import java.util.Date;

import javax.swing.BorderFactory;
import javax.swing.BoxLayout;
import javax.swing.ButtonGroup;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.plaf.DimensionUIResource;

/**
 * A frame that contains settings for selecting various option dialogs.
 * @author Ronaldqinbiao
 *
 */
public class OptionDialogFrame extends JFrame {
	
	private ButtonPanel typePanel;
	private ButtonPanel messagePanel;
	private ButtonPanel messageTypePanel;
	private ButtonPanel optionTypePanel;
	private ButtonPanel optionsPanel;
	private ButtonPanel inputPanel;
	private String messageString = "Message";
	private Icon messageIcon = new ImageIcon("...");
	private Object messageObject = new Date();
	private Component messageComponent = new SampleComponent();
	
	
	public OptionDialogFrame(){
		JPanel gridPanel = new JPanel();
		gridPanel.setLayout(new GridLayout(2, 3));
		typePanel = new  ButtonPanel("Type", "Message", "Confirm", "Option", "Input");
		messageTypePanel = new ButtonPanel("Message Type", "ERROR_MESSAGE", "INFORMATION_MESSAGE",
				"WARNING_MESSAGE", "QUESTION_MESSAGE", "PLAIN_MESSAGE");
		messagePanel = new ButtonPanel("Message", "String", "Icon", "Component", "Other", "Object[]");
		optionTypePanel = new ButtonPanel("Confirm", "DEFAULT_OPTION", "YES_NO_OPTION", 
				"YES_NO_CANCEL_OPTION", "OK_CANCEL_OPTION");
		optionsPanel = new ButtonPanel("Option", "String[]", "Icon[]", "Object[]");
		inputPanel = new ButtonPanel("Input", "Text field", "Combo box");
		
		gridPanel.add(typePanel);
		gridPanel.add(messageTypePanel);
		gridPanel.add(messagePanel);
		gridPanel.add(optionTypePanel);
		gridPanel.add(optionsPanel);
		gridPanel.add(inputPanel);
		
		// add a panel with a show button
		
		JPanel showPanel = new JPanel();
		JButton showButton = new JButton("Show");
		showButton.addActionListener(new ShowAction());
		showPanel.add(showButton);
		
		add(gridPanel, BorderLayout.CENTER);
		add(showPanel, BorderLayout.SOUTH);
				
		this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		this.setVisible(true);
		this.pack();
		
	}
	
	/**
	 * Gets the currently selected message.
	 * @return a string, icon, component, or object array, depending on the Message panel selection
	 */
	public Object getMessage(){
		String s = messagePanel.getSelection();
		if (s.equals("String")) return messageString;
		else if (s.equals("Icon")) return messageIcon;
		else if (s.equals("Component")) return messageComponent;
		else if (s.equals("Object[]")) return new Object[] { messageString, messageIcon,
				messageComponent, messageObject	};
		else if (s.equals("Other")) return messageObject;
		else return null;
	}
	
	
	/**
	 * Gets the currently selected options.
	 * @return an array of strings, icons, or objects, depending on the Option panel selection
	 */
	public Object[] getOptions(){
		String s = optionsPanel.getSelection();
		if (s.equals("String[]")) return new String[] { "Yellow", "Blue", "Red" };
		else if (s.equals("Icon[]")) return new Icon[] { new ImageIcon("yellow-ball.gif"),
				new ImageIcon("blue-ball.gif"), new ImageIcon("red-ball.gif") };
		else if (s.equals("Object[]")) return new Object[] {messageString, messageIcon,
				messageComponent, messageObject	};
		else return null;
	}
	
	/**
	 * Gets the selected message or option type
	 * @param panel the Message Type or Confirm panel
	 * @return the selected XXX_MESSAGE or XXX_OPTION constant from the JOptionPane class
	 */
	public int getType(ButtonPanel panel){
		String s = panel.getSelection();
		try {
			return JOptionPane.class.getField(s).getInt(null);
		}catch (Exception e) {
			// TODO: handle exception
			return -1;
		}
	}
	
	public static void main(String[] args){
		new OptionDialogFrame();
	}
	
	/**
	 * The action listener for the Show button shows a Conform, Input, Message, or Option dialog
	 * depending on the Type panel selection.
	 * @author Ronaldqinbiao
	 *
	 */
	private class ShowAction implements ActionListener{
		public void actionPerformed(ActionEvent event){
			
			//ConfirmDialog
			if(typePanel.getSelection().equals("Confirm")) JOptionPane.showConfirmDialog(
					OptionDialogFrame.this, getMessage(), "Title", getType(optionsPanel),
					getType(messageTypePanel));
			
			//InputDialog
			else if (typePanel.getSelection().equals("Input")){
				
				//Text field InputDialog
				if (inputPanel.getSelection().equals("Text field")) JOptionPane.showInputDialog(
						OptionDialogFrame.this, getMessage(), "Title", getType(messageTypePanel));
				
				//Combo box InputDialog
				else JOptionPane.showInputDialog(OptionDialogFrame.this, getMessage(), "Title",
						getType(messagePanel), null, new String[] { "Yellow", "Blue", "Red" },
						"Blue");
			}
			
			//MessageDialog
			else if (typePanel.getSelection().equals("Message")) JOptionPane.showMessageDialog(
					OptionDialogFrame.this, getMessage(), "Title", getType(messageTypePanel));
			
			//OptionDialog
			else if (typePanel.getSelection().equals("Option")) JOptionPane.showOptionDialog(
					OptionDialogFrame.this, getMessage(), "Title", getType(optionTypePanel),
					getType(messageTypePanel), null, getOptions(), getOptions()[0]);
		}
	}
}
/**
 * A component with a painted surface
 * @author Ronaldqinbiao
 *
 */
class SampleComponent extends JComponent{
	public void paintComponent(Graphics g){
		Graphics2D g2 = (Graphics2D) g;
		Rectangle2D rect = new Rectangle2D.Double(0, 0, getWidth() - 1, getHeight() - 1);
		g2.setPaint(Color.YELLOW);
		g2.fill(rect);
		g2.setPaint(Color.BLUE);
		g2.draw(rect);
	}
	
	public Dimension getPreferredSize(){
		return new DimensionUIResource(10, 10);
	}
}

/**
 * A panel with radio buttons inside a titled border.
 * @author Ronaldqinbiao
 *
 */
class ButtonPanel extends JPanel {
	private ButtonGroup group;
	
	/**
	 * Constructs a button panel.
	 * @param title the title shown in the border
	 * @param options options an array of radio button labels
	 */
	public ButtonPanel(String title, String ... options){
		setBorder(BorderFactory.createTitledBorder(BorderFactory.createEtchedBorder(), title));
		setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
		group = new ButtonGroup();
		for(String option : options){
			JRadioButton b = new JRadioButton(option);
			b.setActionCommand(option);
			add(b);
			group.add(b);
			b.setSelected(option == options[0]);
		}
	}
	
	/**
	 * Gets the currently selected option.
	 * @return the label of hte currently selected radio button.
	 */
	public String getSelection(){
		return group.getSelection().getActionCommand();
	}
}