/*******************************************************************************
 * Copyright (c) 2006 Sybase, Inc. and others.
 *
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     Sybase, Inc. - initial API and implementation
 *******************************************************************************/
package org.eclipse.jst.pagedesigner.css2.style;

import java.util.HashMap;
import java.util.Map;

import org.eclipse.draw2d.geometry.Insets;
import org.eclipse.jst.pagedesigner.IHTMLConstants;
import org.eclipse.jst.pagedesigner.css2.CSSUtil;
import org.eclipse.jst.pagedesigner.css2.ICSSStyle;
import org.eclipse.jst.pagedesigner.css2.font.CSSFontManager;
import org.eclipse.jst.pagedesigner.css2.font.ICSSFont;
import org.eclipse.jst.pagedesigner.css2.font.ICSSFontManager;
import org.eclipse.jst.pagedesigner.css2.list.CounterHelper;
import org.eclipse.jst.pagedesigner.css2.list.CounterValueGenerator;
import org.eclipse.jst.pagedesigner.css2.list.ICounterValueGenerator;
import org.eclipse.jst.pagedesigner.css2.property.CSSMetaRegistry;
import org.eclipse.jst.pagedesigner.css2.property.ICSSPropertyID;
import org.eclipse.jst.pagedesigner.css2.property.ICSSPropertyMeta;
import org.eclipse.jst.pagedesigner.css2.value.Length;
import org.eclipse.jst.pagedesigner.utils.DOMUtil;
import org.eclipse.wst.sse.core.internal.provisional.INodeNotifier;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.css.CSSStyleDeclaration;
import org.w3c.dom.css.CSSValue;

/**
 * @author mengbo
 */
public class AbstractStyle implements ICSSStyle {
	public static final String ATTR_NAME = "name";

	public static final String ATTR_ID = "id";

	protected Element _element;

	private Map _cachedValues = new HashMap();

	private ICSSFont _font = null;

	private CSSStyleDeclaration _cache;

	private CSSStyleDeclaration _defaultCache;

	private boolean _cssDeclareWasSearched = false;

	private boolean _cssDefaultDeclareWasSearched = false;

	private Insets _borderInsets, _marginInsets, _paddingInsets;

	private ICSSStyle _parentStyle;

	private HashMap _counters = null;

	public Element getElement() {
		return _element;
	}

	public AbstractStyle(Element element) {
		_element = element;
	}

	/**
	 * reset all the cache.
	 */
	public void reset() {
		_cachedValues.clear();
		_font = null;
		_cache = null;
		_defaultCache = null;
		_cssDeclareWasSearched = false;
		_cssDefaultDeclareWasSearched = false;
		// if (_counters != null)
		// {
		// unregistCounter();
		// _counters.clear();
		// _counters = null;
		// }
		_borderInsets = _marginInsets = _paddingInsets = null;
	}

	/**
	 * this is a hook method so caller can use it to override default
	 * calculation. Note, after the call to <code>reset</code>, it will be
	 * lost.
	 * 
	 * @param property
	 * @param value
	 */
	public void setStyleProperty(String property, Object value) {
		_cachedValues.put(property, value);
	}

	/**
	 * get a style property value.
	 * 
	 * @param property
	 * @return
	 */
	public Object getStyleProperty(String property) {
		Object value = _cachedValues.get(property);
		if (value == null) {
			value = calculateProperty(property);
			if (value != null) {
				_cachedValues.put(property, value);
			}
		}
		return value;
	}

	/**
	 * in this method, should first check the "style" attribute, then combine
	 * that with document style.
	 * 
	 * @return
	 */
	protected CSSStyleDeclaration calculateDeclaration() {
		String name = getHtmlElement().getAttribute("id");
		if (name == null || name.length() == 0) {
			name = getHtmlElement().getAttribute("name");
		}
		return CSSUtil.getCSSDeclaration(this.getHtmlElement(), name);
	}

	protected CSSStyleDeclaration calculateDefaultDeclaration() {
		return CSSUtil.getDefaultCSSDeclaration(this.getHtmlElement(), null);
	}

	public CSSStyleDeclaration getDeclaration() {
		// FIXME:may need to be change, boolean variable is not a best way.
		if (!_cssDeclareWasSearched) {
			_cache = calculateDeclaration();
			_cssDeclareWasSearched = true;
		}
		return _cache;
	}

	public CSSStyleDeclaration getDefaultDeclaration() {
		// FIXME:may need to be change, boolean variable is not a best way.
		if (!_cssDefaultDeclareWasSearched) {
			_defaultCache = calculateDefaultDeclaration();
			_cssDefaultDeclareWasSearched = true;
		}
		return _defaultCache;
	}

	public Object getHTMLelementInitValue(String propertyName) {
		ICSSPropertyMeta meta = getPropertyMeta(propertyName);
		if (meta != null) {
			Object obj = meta.getHTMLElementInitialValue(_element,
					getHTMLTag(), propertyName);
			if (obj == null) {
				obj = meta.getInitialValue(propertyName, this);
			}
			return obj;
		}
		return ICSSPropertyMeta.NOT_SPECIFIED;
	}

	protected Object calculateProperty(String propertyName) {
		ICSSPropertyMeta meta = getPropertyMeta(propertyName);
		Object result = null;
		// get declaration
		CSSStyleDeclaration decl = getDeclaration();
		CSSValue value = decl == null ? null : decl
				.getPropertyCSSValue(propertyName);
		if (value == null) {
			if (meta != null) {
				result = meta.calculateHTMLAttributeOverride(_element,
						getHTMLTag(), propertyName, this);
				if (result != null) {
					return result;
				}
			}
			decl = getDefaultDeclaration();
		}
		value = decl == null ? null : decl.getPropertyCSSValue(propertyName);

		if (value != null && value.getCssValueType() == CSSValue.CSS_INHERIT) {
			result = getParentResultValue(meta, propertyName);
		} else if (value == null) {
			if (meta != null) {
				result = meta.calculateHTMLAttributeOverride(_element,
						getHTMLTag(), propertyName, this);
			}
			if (result == null) {
				result = calculateLocalOverride(meta, propertyName);
			}
			if (result == null) {
				if (meta == null) {
					result = ICSSPropertyMeta.NOT_SPECIFIED;
				} else {
					if (meta.isInherited()) {
						result = getParentResultValue(meta, propertyName);
					} else {
						result = meta.getInitialValue(propertyName, this);
					}
				}
			}
		} else {
			result = calculateCSSValueResult(meta, value, propertyName);
		}
		return result;
	}

	/**
	 * get the corresponding HTML tag for this style. This is for certain HTML
	 * tag can also provide style information.
	 * 
	 * @return
	 */
	protected String getHTMLTag() {
		return _element.getTagName();
	}

	/**
	 * @param propertyName
	 * @return
	 */
	protected ICSSPropertyMeta getPropertyMeta(String propertyName) {
		return CSSMetaRegistry.getInstance().getMeta(propertyName);
	}

	/**
	 * convert the CSSValue to the property type specified data result.
	 * 
	 * @param value
	 * @param propertyName
	 * @return should not return null.
	 */
	protected Object calculateCSSValueResult(ICSSPropertyMeta meta,
			CSSValue value, String propertyName) {
		if (meta == null) {
			return ICSSPropertyMeta.NOT_SPECIFIED;
		} else {
			return meta.calculateCSSValueResult(value, propertyName, this);
		}
	}

	/**
	 * it is possible that some attribute of the element may provide style
	 * information. child class should override this method. Also, some element
	 * type may have internally build style, such as input-submit may use
	 * special border. NOTE: it is very important that in calculateLocalOverride
	 * you don't directly or indirectly call getStyleProperty() to avoid
	 * deadloop.
	 * 
	 * @param propertyName
	 * @return null means no style information in other attributes. Otherwise
	 *         return property specific data result -- normally will use meta to
	 *         convert the attribute.
	 */
	protected Object calculateLocalOverride(ICSSPropertyMeta meta,
			String propertyName) {
		// // do some default margin thing.
		// if (ICSSPropertyID.ATTR_MARGIN_RIGHT.equalsIgnoreCase(propertyName)
		// || ICSSPropertyID.ATTR_MARGIN_BOTTOM.equalsIgnoreCase(propertyName))
		// {
		// return MARGIN_LENGTH;
		// }
		// else if
		// (ICSSPropertyID.ATTR_MARGIN_LEFT.equalsIgnoreCase(propertyName))
		// {
		// // to make a little room, so it is possible for user to position the
		// // mouse before the first element in a block.
		// return MARGIN_LEFT;
		// }
		return null;
	}

	/**
	 * This is only called when inherit value from parent.
	 * 
	 * @param propertyName
	 * @return
	 */
	protected Object getParentResultValue(ICSSPropertyMeta meta,
			String propertyName) {
		ICSSStyle style = getParentStyle();
		return style.getStyleProperty(propertyName);
	}

	public void setParentStyle(ICSSStyle parentStyle) {
		this._parentStyle = parentStyle;
		reset();
	}

	public ICSSStyle getParentStyle() {
		if (_parentStyle != null) {
			return _parentStyle;
		}
		Node node = _element.getParentNode();
		while (node instanceof Element && node instanceof INodeNotifier) {
			ICSSStyle parentStyle = (ICSSStyle) ((INodeNotifier) node)
					.getAdapterFor(ICSSStyle.class);
			if (parentStyle != null) {
				return parentStyle;
			} else {
				node = node.getParentNode();
			}
		}
		return DefaultStyle.getInstance();
	}

	/**
	 * Will not return null
	 * 
	 * @return
	 */
	public ICSSFont getCSSFont() {
		if (_font == null) {
			_font = getFontManager().createFont(this);
		}
		return _font;
	}

	/**
	 * @return
	 */
	private ICSSFontManager getFontManager() {
		return CSSFontManager.getInstance();
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.jst.pagedesigner.css2.ICSSStyle#dispose()
	 */
	public void dispose() {
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.jst.pagedesigner.css2.ICSSStyle#getMarginInsets()
	 */
	public Insets getMarginInsets() {
		if (_marginInsets == null) {
			int top = getInsetProperty(ICSSPropertyID.ATTR_MARGIN_TOP);
			int left = getInsetProperty(ICSSPropertyID.ATTR_MARGIN_LEFT);
			int bottom = getInsetProperty(ICSSPropertyID.ATTR_MARGIN_BOTTOM);
			int right = getInsetProperty(ICSSPropertyID.ATTR_MARGIN_RIGHT);
			_marginInsets = new Insets(top, left, bottom, right);
		}
		return _marginInsets;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.jst.pagedesigner.css2.ICSSStyle#getPaddingInsets()
	 */
	public Insets getPaddingInsets() {
		if (_paddingInsets == null) {
			int top = getInsetProperty(ICSSPropertyID.ATTR_PADDING_TOP);
			int left = getInsetProperty(ICSSPropertyID.ATTR_PADDING_LEFT);
			int bottom = getInsetProperty(ICSSPropertyID.ATTR_PADDING_BOTTOM);
			int right = getInsetProperty(ICSSPropertyID.ATTR_PADDING_RIGHT);
			_paddingInsets = new Insets(top, left, bottom, right);
		}
		return _paddingInsets;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.jst.pagedesigner.css2.ICSSStyle#getBorderInsets()
	 */
	public Insets getBorderInsets() {
		if (_borderInsets == null) {
			int top = getInsetProperty(ICSSPropertyID.ATTR_BORDER_TOP_WIDTH);
			int left = getInsetProperty(ICSSPropertyID.ATTR_BORDER_LEFT_WIDTH);
			int bottom = getInsetProperty(ICSSPropertyID.ATTR_BORDER_BOTTOM_WIDTH);
			int right = getInsetProperty(ICSSPropertyID.ATTR_BORDER_RIGHT_WIDTH);
			_borderInsets = new Insets(top, left, bottom, right);
		}
		return _borderInsets;
	}

	/**
	 * @param border_top_width
	 * @return
	 */
	private int getInsetProperty(String propertyName) {
		Object obj = this.getStyleProperty(propertyName);
		if (obj instanceof Length) {
			Length l = (Length) obj;
			if (l.isPercentage()) {
				return 0; // FIXME:
			} else {
				return l.getValue();
			}
		}

		return 0;
	}

	public boolean isAdapterForType(Object type) {
		return (type == ICSSStyle.class);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.jst.pagedesigner.css2.ICSSStyle#isSizeIncludeBorderPadding()
	 */
	public boolean isSizeIncludeBorderPadding() {
		String display = this.getDisplay();
		if ("table-cell".equalsIgnoreCase(display)) {
			return false;
		}
		String tag = this.getHTMLTag();
		if ("img".equalsIgnoreCase(tag)) {
			return false;
		}
		return true;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.ibm.sse.model.INodeAdapter#notifyChanged(com.ibm.sse.model.INodeNotifier,
	 *      int, java.lang.Object, java.lang.Object, java.lang.Object, int)
	 */
	public void notifyChanged(INodeNotifier notifier, int eventType,
			Object changedFeature, Object oldValue, Object newValue, int pos) {
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.jst.pagedesigner.css2.ICSSStyle#getBackgroundColor()
	 */
	public Object getColor() {
		Object _color = null;
		if (_color == null) {
			_color = getStyleProperty(ICSSPropertyID.ATTR_COLOR);
			if (_color == null) {
				_color = getStyleProperty(ICSSPropertyID.ATTR_TEXTCOLOR);
			}
		}
		return _color;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.jst.pagedesigner.css2.ICSSStyle#getColor()
	 */
	public Object getBackgroundColor() {
		Object _backgroundColor = null;
		if (_backgroundColor == null) {
			_backgroundColor = getStyleProperty(ICSSPropertyID.ATTR_BACKGROUND_COLOR);
		}
		return _backgroundColor;
	}

	public Element getHtmlElement() {
		// if (_element instanceof IDOMElement)
		// {
		// EditPart part = (EditPart) ((IDOMElement)
		// _element).getAdapterFor(EditPart.class);
		// if (part instanceof ElementEditPart)
		// {
		// ElementEditPart elementPart = (ElementEditPart) part;
		// ITagHandler h = elementPart.getTagHandler();
		// if (h != null)
		// {
		// return h.mapCustomElement(_element);
		// }
		// }
		//
		// }
		return _element;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.jst.pagedesigner.css2.ICSSStyle#getDisplay()
	 */
	public String getDisplay() {
		Object display = this.getStyleProperty(ICSSPropertyID.ATTR_DISPLAY);
		String displayStr;
		if (display == null) {
			displayStr = ICSSPropertyID.VAL_INLINE;
		} else if (display instanceof String) {
			displayStr = (String) display;
		} else {
			displayStr = display.toString();
		}
		if (ICSSPropertyID.VAL_INLINE.equalsIgnoreCase(displayStr)
				&& IHTMLConstants.TAG_TABLE.equalsIgnoreCase(getHTMLTag())) {
			return ICSSPropertyID.VAL_INLINE_TABLE;
		}
		if (ICSSPropertyID.VAL_INLINE.equalsIgnoreCase(displayStr)) {
			Object width = this.getStyleProperty(ICSSPropertyID.ATTR_WIDTH);
			if (width instanceof Length) {
				return ICSSPropertyID.VAL_INLINE_BLOCK;
			}
			Object height = this.getStyleProperty(ICSSPropertyID.ATTR_HEIGHT);
			if (height instanceof Length) {
				return ICSSPropertyID.VAL_INLINE_BLOCK;
			}
			return displayStr;
		} else {
			return displayStr;
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.jst.pagedesigner.css2.ICSSStyle#getListStyle()
	 */
	public Map getCounters() {
		if (_counters == null) {
			_counters = new HashMap();
			CounterHelper.processCounterReset(this, _counters);
		}
		return _counters;
	}

	/**
	 * Get named counter from counters.
	 * 
	 * @see org.eclipse.jst.pagedesigner.css2.ICSSStyle#getCounter(java.lang.String)
	 */
	public ICounterValueGenerator findCounter(String name, boolean must) {
		Map counters = getCounters();
		if (counters == null || !counters.containsKey(name)) {
			if (getParentStyle() != null
					&& !(getParentStyle() instanceof DefaultStyle)) {
				// ensure it is registered somewhere.
				return getParentStyle().findCounter(name, must);
			}
			// must is called by counter-increment
			else if (must) {
				// the caller should do the other setting.
				ICounterValueGenerator counter = new CounterValueGenerator(
						name, null, null, this);
				counter.resetCount();
				counters.put(name, counter);
			}
		}
		return (ICounterValueGenerator) counters.get(name);
	}

	/**
	 * @param buffer
	 */
	public void dumpDebugInfo(StringBuffer buffer) {
		if (_cache != null) {
			buffer.append("cache:\n");
			buffer.append(_cache.getCssText()).append("\n");
		}
		if (_defaultCache != null) {
			buffer.append("default cache:\n");
			buffer.append(_defaultCache.getCssText()).append("\n");
		}

	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.jst.pagedesigner.css2.ICSSStyle#getColSpan()
	 */
	public int getColSpan() {
		int colspan = DOMUtil.getIntAttributeIgnoreCase(getHtmlElement(),
				"colspan", 1);
		// if span == 0, means span all col from the current column to end
		// colume
		if (colspan < 0) {
			return 1;
		} else {
			return colspan;
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.jst.pagedesigner.css2.ICSSStyle#getRowSpan()
	 */
	public int getRowSpan() {
		int rowspan = DOMUtil.getIntAttributeIgnoreCase(getHtmlElement(),
				"rowspan", 1);
		if (rowspan < 0) {
			return 1;
		} else {
			return rowspan;
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.jst.pagedesigner.css2.ICSSStyle#isInSelection()
	 */
	public boolean isInSelection() {
		IRangeSelectionProxy proxy = (IRangeSelectionProxy) getAdapter(IRangeSelectionProxy.class);
		if (proxy != null) {
			return proxy.isRangeSelected();
		}
		ICSSStyle parentStyle = getParentStyle();
		if (parentStyle != null) {
			return parentStyle.isInSelection();
		}
		return false;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.core.runtime.IAdaptable#getAdapter(java.lang.Class)
	 */
	public Object getAdapter(Class adapter) {
		if (this._element instanceof INodeNotifier) {
			Object ret = ((INodeNotifier) _element).getAdapterFor(adapter);
			if (ret != null && adapter.isInstance(ret)) {
				return ret;
			}
		}
		return null;
	}

	// private void unregistCounter()
	// {
	// if (_counters != null)
	// {
	// Collection c = _counters.values();
	// Iterator iter = c.iterator();
	// while (iter.hasNext())
	// {
	// Counter2 counter = (Counter2) iter.next();
	// counter.unregist(this);
	// }
	// }
	// }

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.jst.pagedesigner.css2.ICSSStyle#resetCounters()
	 */
	public void processCounters() {
		this._counters = null;
		CounterHelper.processCounterIncrement(this);
	}
}
