package com.gitblit.models;

import java.io.Serializable;

import org.apache.wicket.PageParameters;
import org.apache.wicket.markup.html.WebPage;

import com.gitblit.utils.StringUtils;

public class Menu {

	/**
	 * A MenuItem for a drop down menu.
	 *
	 * @author James Moger
	 * @since 1.6.0
	 */
	public abstract static class MenuItem implements Serializable {

		private static final long serialVersionUID = 1L;

		final String displayText;

		MenuItem(String displayText) {
			this.displayText = displayText;
		}

		@Override
		public int hashCode() {
			return displayText.hashCode();
		}

		@Override
		public boolean equals(Object o) {
			if (o instanceof MenuItem) {
				return hashCode() == o.hashCode();
			}
			return false;
		}

		@Override
		public String toString() {
			return displayText;
		}
	}

	/**
	 * A divider for the menu.
	 *
	 * @since 1.6.0
	 */
	public static class MenuDivider extends MenuItem {

		private static final long serialVersionUID = 1L;

		public MenuDivider() {
			super("");
		}
	}


	/**
	 * A MenuItem for setting a parameter of the current url.
	 *
	 * @author James Moger
	 *
	 */
	public static class ParameterMenuItem extends MenuItem {

		private static final long serialVersionUID = 1L;

		final PageParameters parameters;
		final String parameter;
		final String value;
		final boolean isSelected;

		/**
		 * @param displayText
		 */
		public ParameterMenuItem(String displayText) {
			this(displayText, null, null, null);
		}

		/**
		 * @param displayText
		 * @param parameter
		 * @param value
		 */
		public ParameterMenuItem(String displayText, String parameter, String value) {
			this(displayText, parameter, value, null);
		}

		/**
		 * @param displayText
		 * @param parameter
		 * @param value
		 */
		public ParameterMenuItem(String displayText, String parameter, String value,
				PageParameters params) {
			super(displayText);
			this.parameter = parameter;
			this.value = value;

			if (params == null) {
				// no parameters specified
				parameters = new PageParameters();
				setParameter(parameter, value);
				isSelected = false;
			} else {
				parameters = new PageParameters(params);
				if (parameters.containsKey(parameter)) {
					isSelected = params.getString(parameter).equals(value);
					// set the new selection value
					setParameter(parameter, value);
				} else {
					// not currently selected
					isSelected = false;
					setParameter(parameter, value);
				}
			}
		}

		protected void setParameter(String parameter, String value) {
			if (!StringUtils.isEmpty(parameter)) {
				if (StringUtils.isEmpty(value)) {
					this.parameters.remove(parameter);
				} else {
					this.parameters.put(parameter, value);
				}
			}
		}

		public String formatParameter() {
			if (StringUtils.isEmpty(parameter) || StringUtils.isEmpty(value)) {
				return "";
			}
			return parameter + "=" + value;
		}

		public PageParameters getPageParameters() {
			return parameters;
		}

		public boolean isSelected() {
			return isSelected;
		}

		@Override
		public int hashCode() {
			if (StringUtils.isEmpty(displayText)) {
				return value.hashCode() + parameter.hashCode();
			}
			return displayText.hashCode();
		}

		@Override
		public boolean equals(Object o) {
			if (o instanceof MenuItem) {
				return hashCode() == o.hashCode();
			}
			return false;
		}

		@Override
		public String toString() {
			if (StringUtils.isEmpty(displayText)) {
				return formatParameter();
			}
			return displayText;
		}
	}

	/**
	 * Menu item for toggling a parameter.
	 *
	 */
	public static class ToggleMenuItem extends ParameterMenuItem {

		private static final long serialVersionUID = 1L;

		/**
		 * @param displayText
		 * @param parameter
		 * @param value
		 */
		public ToggleMenuItem(String displayText, String parameter, String value,
				PageParameters params) {
			super(displayText, parameter, value, params);
			if (isSelected) {
				// already selected, so remove this enables toggling
				parameters.remove(parameter);
			}
		}
	}

	/**
	 * Menu item for linking to another Wicket page.
	 *
	 * @since 1.6.0
	 */
	public static class PageLinkMenuItem extends MenuItem {

		private static final long serialVersionUID = 1L;

		private final Class<? extends WebPage> pageClass;

		private final PageParameters params;

		/**
		 * Page Link Item links to another page.
		 *
		 * @param displayText
		 * @param pageClass
		 * @since 1.6.0
		 */
		public PageLinkMenuItem(String displayText, Class<? extends WebPage> pageClass) {
			this(displayText, pageClass, null);
		}

		/**
		 * Page Link Item links to another page.
		 *
		 * @param displayText
		 * @param pageClass
		 * @param params
		 * @since 1.6.0
		 */
		public PageLinkMenuItem(String displayText, Class<? extends WebPage> pageClass, PageParameters params) {
			super(displayText);
			this.pageClass = pageClass;
			this.params = params;
		}

		/**
		 * @return the page class
		 * @since 1.6.0
		 */
		public Class<? extends WebPage> getPageClass() {
			return pageClass;
		}

		/**
		 * @return the page parameters
		 * @since 1.6.0
		 */
		public PageParameters getPageParameters() {
			return params;
		}
	}

	/**
	 * Menu item to link to an external page.
	 *
	 * @since 1.6.0
	 */
	public static class ExternalLinkMenuItem extends MenuItem {

		private static final long serialVersionUID = 1L;

		private final String href;

		private final boolean newWindow;

		/**
		 * External Link Item links to something else.
		 *
		 * @param displayText
		 * @param href
		 * @since 1.6.0
		 */
		public ExternalLinkMenuItem(String displayText, String href) {
			this(displayText, href, false);
		}

		/**
		 * External Link Item links to something else.
		 *
		 * @param displayText
		 * @param href
		 * @since 1.6.0
		 */
		public ExternalLinkMenuItem(String displayText, String href, boolean newWindow) {
			super(displayText);
			this.href = href;
			this.newWindow = newWindow;
		}

		/**
		 * @since 1.6.0
		 */
		public String getHref() {
			return href;
		}

		/**
		 * @since 1.6.0
		 */
		public boolean openInNewWindow() {
			return newWindow;
		}
	}
}
