/*******************************************************************************
 * 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;
		}
        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;
			}
            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() {
        // TODO: anything to 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)+ARTIFICIAL_BORDER_OFFSET;
			int left = getInsetProperty(ICSSPropertyID.ATTR_PADDING_LEFT)+ARTIFICIAL_BORDER_OFFSET;
			int bottom = getInsetProperty(ICSSPropertyID.ATTR_PADDING_BOTTOM)+ARTIFICIAL_BORDER_OFFSET;
			int right = getInsetProperty(ICSSPropertyID.ATTR_PADDING_RIGHT)+ARTIFICIAL_BORDER_OFFSET;
			_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:
			}
            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) {
        // do nothing
	}

	/*
	 * (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;
		}
        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;
		}
        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;
		}
        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);
	}
}
