/*
 *	Modulname:	RendererMultipleChoice
 *	Autor:		Eyer Leander
 *	Datum:		08.05.2006
 *
 *	(c) Copyright 2005
 */
package survey.gui;

import info.clearthought.layout.TableLayout;
import survey.Survey;
import survey.model.Choice;
import survey.model.Question;
import survey.model.TypeMultiChoice;

import javax.swing.*;
import javax.swing.text.html.HTMLEditorKit;
import javax.swing.text.html.StyleSheet;
import javax.swing.text.Document;
import java.awt.*;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.util.Iterator;
import java.util.Vector;
import java.io.StringReader;

/**
 * A renderer for multiple choice questions
 */
public class RendererMultipleChoice extends Renderer implements ItemListener {

	// connection to the model
	private TypeMultiChoice type;

    private JLabel questionLabel;
//	private JTextPane questionLabel;
	private JPanel answerPane;

	// radio buttons
	private Vector<JRadioButton> radioButtons = new Vector<JRadioButton>();

	/**
	 * Constructor
	 */
	public RendererMultipleChoice(Question element, TypeMultiChoice type) {
		super(element);
		this.type = type;

		createUI();
		setEditable(getQuestion().isEditable());
	}

	/**
	 * Config the user interface
	 */
	private void createUI() {
		//setLayout(new BorderLayout(6, 6));
		String mandatoryFlag = getQuestion().isMandatory() ? "* " : "";

		String labelContent = "<html><body>" + mandatoryFlag + getQuestion().getLabel() + "</body></html>";

/*		questionLabel = new JTextPane();
		HTMLEditorKit htmlKit = new HTMLEditorKit();
		StyleSheet styleSheet = new StyleSheet();
		htmlKit.setStyleSheet(styleSheet);
		questionLabel.setEditorKit(htmlKit);
		Document doc = htmlKit.createDefaultDocument();
		try {
			htmlKit.read(new StringReader(labelContent), doc, 0);
		} catch (Exception e) {
			e.printStackTrace();
		}
		questionLabel.setDocument(doc);
		questionLabel.setOpaque(false);
*/
		questionLabel = new JLabel(labelContent);

		ButtonGroup group = new ButtonGroup();
		int rows = type.isVertical() ? 0 : 1;
		int cols = type.isVertical() ? 1 : 0;
		answerPane = new JPanel(new BorderLayout(12, 12));

		if (type.getLeftLabel().equals("") == false) {
			JLabel label = new JLabel(type.getLeftLabel());
			label.setHorizontalAlignment(JLabel.CENTER);
			answerPane.add(label, BorderLayout.WEST);
		}

		JPanel itemPane = new JPanel(new GridLayout(rows, cols, 6, 6));
		Iterator<Choice> choices = type.getChoices();
		while (choices.hasNext()) {
			Choice choice = choices.next();
			JRadioButton button = new JRadioButton(choice.getLabel());
			button.setFont(Survey.FONT_QUESTION_ANSWER);
			button.addItemListener(this);
			button.putClientProperty("choice", choice);

			group.add(button);
			itemPane.add(button);

			radioButtons.add(button);
		}
		answerPane.add(itemPane, BorderLayout.CENTER);


		if (type.getRightLabel().equals("") == false) {
			JLabel label = new JLabel(type.getRightLabel());
			label.setHorizontalAlignment(JLabel.CENTER);
			answerPane.add(label, BorderLayout.EAST);
		}


		if (type.isVertical() || type.startNewline()) {
			//setLayout(new BorderLayout(6, 6));
			//add(questionLabel, BorderLayout.CENTER);
			//add(answerPane, BorderLayout.SOUTH);

			setLayout(new TableLayout(new double[][]{{TableLayout.PREFERRED}, {TableLayout.PREFERRED, 6, TableLayout.PREFERRED}}));
			add(questionLabel, "0, 0");
			add(answerPane, "0, 2");
		} else {
			//setLayout(new BorderLayout(24, 24));
			//add(questionLabel, BorderLayout.CENTER);
			//add(answerPane, BorderLayout.EAST);

		        //TODO: workaround. the last line of the label gets cut.
 		        if (questionLabel.getPreferredSize().getWidth() > 480) {
			    labelContent = "<html><body>" + mandatoryFlag + getQuestion().getLabel() + "<br> </br>&nbsp;</body></html>";
			    questionLabel = new JLabel(labelContent);
			}

			setLayout(new TableLayout(new double[][]{{500, 24, TableLayout.FILL}, {TableLayout.PREFERRED}}));
			add(questionLabel, "0, 0");
			add(answerPane, "2, 0, R, T");
		}

	}

	/**
	 * Invoked when an item has been selected or deselected by the user.
	 * The code written for this method performs the operations
	 * that need to occur when an item is selected (or deselected).
	 */
	public void itemStateChanged(ItemEvent e) {
		// Filter deselect events out
		if (e.getStateChange() == ItemEvent.DESELECTED) {
			return;
		}

		//search the active element
		for (JRadioButton button : radioButtons) {
			if (button.isSelected()) {
				Choice choice = (Choice) button.getClientProperty("choice");
				type.setAnswer(choice);
			}
		}
	}

	/**
	 * Update the question state (i.e. after a model element has been set programatically)
	 */
	public void updateRenderer() {
	        String answerId = (String) getQuestion().getContentType().getAnswer();
		if (answerId == null) {
		    //TODO!!! unselect all the buttons: not easy workaround
		    return;
		}

		//search the active element
		for (JRadioButton button : radioButtons) {
		    if ( ((Choice)button.getClientProperty("choice")).getId().equals(answerId)) {
				button.setSelected(true);
				return;
			}
		}
		throw new Error("answerId not expected: " + answerId);
	}

	/**
	 * Change the Editable property
	 */
	public void setEditable(boolean editable) {
		for (JRadioButton btn : radioButtons) {
			btn.setEnabled(editable);
		}
	}

	/**
	 * Get the preferred width of the question label
	 */
	public double getLabelWidth() {
		return questionLabel.getPreferredSize().width;
	}

	/**
	 * Set the width of the question label
	 */
	public void setLabelWidth(double width) {
		Dimension d = new Dimension((int) width, questionLabel.getPreferredSize().height);
		questionLabel.setMinimumSize(d);
		questionLabel.setPreferredSize(d);
		questionLabel.setMaximumSize(d);
	}

	/**
	 * Get the size of the answer space
	 */
	public double getAnswerSpaceWidth() {
		return answerPane.getPreferredSize().width;
	}

	/**
	 * Set the answer space width
	 */
	public void setAnswerSpaceWdith(double width) {
		Dimension d = new Dimension((int) width, answerPane.getPreferredSize().height);
		answerPane.setMinimumSize(d);
		answerPane.setPreferredSize(d);
		answerPane.setMaximumSize(d);
	}
}

