package com.hero.ui.widgets;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.FontMetrics;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.Toolkit;

import javax.swing.BorderFactory;
import javax.swing.JComponent;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextArea;

/**
 * Copyright (c) 2000 - 2005, CompNet Design, Inc. All rights reserved.
 * Redistribution and use in source and binary forms, with or without
 * modification, is prohibited unless the following conditions are met: 1.
 * Express written consent of CompNet Design, Inc. is obtained by the developer.
 * 2. Redistributions must retain this copyright notice. THIS SOFTWARE IS
 * PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS
 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
 * EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 * 
 * @author CompNet Design, Inc.
 * @version $Revision$
 */

class MessageWindow extends JDialog {

	class SizingTextPane extends JTextArea {
		private static final long serialVersionUID = -3624727298744098408L;

		private int minWidth = 200;

		public SizingTextPane() {
			super();
			setWrapStyleWord(true);
			setLineWrap(true);
			setEditable(false);
		}

		@Override
		public Dimension getMaximumSize() {
			return Toolkit.getDefaultToolkit().getScreenSize();
		}

		@Override
		public Dimension getMinimumSize() {
			return getPreferredSize();
		}

		@Override
		public Dimension getPreferredSize() {
			FontMetrics fm = getFontMetrics(getFont());
			int overallWidth = fm.stringWidth(getText());
			int width = overallWidth;
			int lineHeight = fm.getHeight();
			int height = lineHeight;
			int numLines = 1;
			while ((width > minWidth) && (height * 3 < width)) {
				numLines++;
				int requiredLines = 3;
				int checkWidth = overallWidth / numLines;
				int lastSpace = 0;
				int lastLine = 0;
				for (int i = 0; i < getText().length(); i++) {
					String test = getText().substring(lastLine, i);

					if (test.length() > 0) {
						char last = test.charAt(test.length() - 1);
						if ((last == ' ') || (last == '\n') || (last == '\r')
								|| (last == '\t')) {
							lastSpace = i;
						}
					}

					if (fm.stringWidth(test) > checkWidth) {
						requiredLines++;
						if (fm.stringWidth(test) > checkWidth) {
							requiredLines++;
							if (lastSpace == lastLine) {
								lastLine = i;
								lastSpace = i;
							} else {
								lastLine = lastSpace;
								i = lastSpace;
							}
						}
					} else if ((test.length() > 0)
							&& ((test.charAt(test.length() - 1) == '\n') || (test
									.charAt(test.length() - 1) == '\r'))) {
						requiredLines++;
						lastLine = i;
						lastSpace = i;
					}
				}
				int checkHeight = lineHeight * requiredLines;
				if (checkWidth / checkHeight < 2) {
					break;
				}
				width = checkWidth;
				height = checkHeight;
			}
			return new Dimension(width, height);
		}
	}

	private static final long serialVersionUID = -7636027891614060053L;

	private static Color background = new Color(230, 230, 230);

	protected static boolean debug = true;

	protected SizingTextPane editor;

	protected String message = "";

	protected JFrame owner = null;

	protected JComponent parent = null;

	public MessageWindow(JFrame owner, JComponent parent, String message) {
		super(owner, true);
		this.owner = owner;
		this.parent = parent;
		this.message = message;
		editor = new SizingTextPane();
		editor.setText(message);
	}

	protected void init() {
		JPanel pane = new JPanel(new GridBagLayout());
		GridBagConstraints gbc = new GridBagConstraints();
		gbc.fill = GridBagConstraints.BOTH;
		gbc.gridx = 1;
		gbc.gridy = 0;
		gbc.gridwidth = 1;
		gbc.gridheight = 1;
		gbc.weightx = 1;
		gbc.weighty = 1;
		gbc.insets = new Insets(3, 5, 0, 5);
		editor.setOpaque(false);
		pane.add(editor, gbc);
		pane.setBackground(MessageWindow.background);
		pane.setBorder(BorderFactory.createLineBorder(Color.black, 1));
		setContentPane(pane);
		pack();
	}

	private void setLocation() {
		int x = 0;
		int y = 0;
		int screenWidth = Toolkit.getDefaultToolkit().getScreenSize().width;
		int screenHeight = Toolkit.getDefaultToolkit().getScreenSize().height;
		int ownerTopY = (int) owner.getLocationOnScreen().getY();
		int ownerBottomY = ownerTopY + owner.getHeight();
		int parentTopY = (int) parent.getLocationOnScreen().getY();
		int parentBottomY = parentTopY + parent.getHeight();
		int parentLeftX = (int) parent.getLocationOnScreen().getX();
		int parentRightX = parentLeftX + parent.getWidth();
		int height = getHeight();
		int width = getWidth();

		// first we'll set the x-coordinate:
		x = parentLeftX + (parentRightX - parentLeftX) / 2 - width / 2 - 6;
		if (x < 0) { // off the left edge of the screen
			x = 0;
		}
		if (x + width > screenWidth) { // off the right edge of the
			// screen
			x = screenWidth - width;
			if (x < 0) {
				x = x / 2;
				// split the difference if the component is wider than the
				// screen
			}
		}

		// now we'll set the y-coordinate:
		y = parentBottomY;
		if ((y + height > ownerBottomY) || (y + height > screenHeight)) { // goes
			// off
			// the
			// bottom
			// of the owner frame...
			y = parentTopY - height - 5;
			if (y < ownerTopY) { // goes off the top of the owner
				// frame...
				if (parentBottomY + height < screenHeight) {
					// it fits on the screen when off the bottom of the parent
					y = parentBottomY;
				} else {
					if (parentTopY - height > 0) {
						// it fits on the screen when off of the top of the
						// parent
						y = parentTopY - height;
					} else { // component is too big for the screen...just do
						// the best we can
						y = (screenHeight - height) / 2;
					}
				}
			}
		}
		setLocation(x, y);
	}

	/**
	 * Sets the message to be displayed
	 * 
	 * @param val
	 */
	public void setMessage(String val) {
		message = val;
	}

	/**
	 * Sets the parent component that this window is to be displayed around.
	 * 
	 * @param val
	 */
	protected void setParent(JComponent val) {
		parent = val;
	}

	@Override
	public void setVisible(boolean visible) {
		if (visible) {
			setLocation();
		}
		super.setVisible(visible);
	}
}
