/*******************************************************************************
 * Copyright (c)2007 Actuate Corporation.
 * 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:
 *  Actuate Corporation  - initial API and implementation
 *******************************************************************************/

package org.eclipse.birt.report.engine.layout.pdf.util;

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

import org.eclipse.birt.report.engine.content.IStyle;
import org.eclipse.birt.report.engine.css.engine.value.FloatValue;
import org.eclipse.birt.report.engine.css.engine.value.ListValue;
import org.eclipse.birt.report.engine.css.engine.value.Value;
import org.w3c.dom.css.CSSPrimitiveValue;

public abstract class StyleProcessor
{

	abstract void process( IStyle style );

	private static Map tag2Style = new HashMap( );

	protected void setHStyle( IStyle style, float fontSize, float margin )
	{
		setMarginTopAndBottom( style, margin );
		style.setProperty( IStyle.STYLE_FONT_SIZE, createEmValue( fontSize ) );
		style.setProperty( IStyle.STYLE_FONT_WEIGHT, IStyle.BOLD_VALUE );
		style.setProperty( IStyle.STYLE_PAGE_BREAK_AFTER, IStyle.AVOID_VALUE );
	}

	protected void setMarginTopAndBottom( IStyle style, float margin )
	{
		style.setProperty( IStyle.STYLE_MARGIN_TOP, createEmValue( margin ) );
		style.setProperty( IStyle.STYLE_MARGIN_BOTTOM, createEmValue( margin ) );
	}
	
	protected void setFontFamily( IStyle style, Value font )
	{
		ListValue fonts = new ListValue();
		fonts.append( font );
		style.setProperty( IStyle.STYLE_FONT_FAMILY, fonts );
	}

	protected void setFontStyle( IStyle style, Value fontStyle )
	{
		style.setProperty( IStyle.STYLE_FONT_STYLE, fontStyle );
	}

	protected void setFontWeight( IStyle style, Value fontWeight )
	{
		style.setProperty( IStyle.STYLE_FONT_WEIGHT, fontWeight );
	}
	
	/*
	 * The following are the currently supported tags:
	 * ("H1")("H2")("H3")("H4")("H5")("H6") ("A")("ADDRESS")("B")("BODY")("BR")
	 * ("CENTER")("CODE")("DD")("DEL")("DIV") ("DL")("DT")("FONT")("EM")("HEAD")
	 * ("HTML")("I")("IMAGE")("IMG")("INS") ("LI")("OL")("PRE")("P")("SPAN")
	 * ("STRONG")("SUB")("SUP")("TITLE") ("UL")("TT")("U")("TABLE")
	 */
	static
	{
		tag2Style.put( "code", //$NON-NLS-1$
				new StyleProcessor( ) {
					public void process( IStyle style )
					{
						setFontFamily( style, IStyle.MONOSPACE_VALUE );
					}
				} );
		tag2Style.put( "em", //$NON-NLS-1$
				new StyleProcessor( ) {
					public void process( IStyle style )
					{
						setFontStyle( style, IStyle.ITALIC_VALUE );
					}
				} );
		tag2Style.put( "h1", //$NON-NLS-1$
				new StyleProcessor( ) {
					public void process( IStyle style )
					{
						setHStyle( style, 2, 0.67f );
					}
				} );
		tag2Style.put( "h2", //$NON-NLS-1$
				new StyleProcessor( ) {
					public void process( IStyle style )
					{
						setHStyle( style, 1.5f, 0.75f );
					}
				} );
		tag2Style.put( "h3", //$NON-NLS-1$
				new StyleProcessor( ) {
					public void process( IStyle style )
					{
						setHStyle( style, 1.17f, 0.83f );
					}
				} );
		tag2Style.put( "h4", //$NON-NLS-1$
				new StyleProcessor( ) {
					public void process( IStyle style )
					{
						setHStyle( style, 1.12f, 1.12f );
					}
				} );
		tag2Style.put( "h5", //$NON-NLS-1$
				new StyleProcessor( ) {
					public void process( IStyle style )
					{
						setHStyle( style, 0.83f, 1.5f );
					}
				} );
		tag2Style.put( "h6", //$NON-NLS-1$
				new StyleProcessor( ) {
					public void process( IStyle style )
					{
						setHStyle( style, 0.75f, 1.67f );
					}
				} );
		tag2Style.put( "pre", //$NON-NLS-1$
				new StyleProcessor( ) {
					public void process( IStyle style )
					{
						setFontFamily( style, IStyle.MONOSPACE_VALUE );
					}
				} );
		tag2Style.put( "strong", //$NON-NLS-1$
				new StyleProcessor( ) {

					public void process( IStyle style )
					{
						setFontWeight( style, IStyle.BOLD_VALUE );
					}
				} );
		tag2Style.put( "sub", //$NON-NLS-1$
				new StyleProcessor( ) {
					public void process( IStyle style )
					{
						style.setProperty( IStyle.STYLE_VERTICAL_ALIGN,
								IStyle.BOTTOM_VALUE );
						style.setProperty( IStyle.STYLE_FONT_SIZE,
								createPercentageValue( 75 ) );
					}
				} );
		tag2Style.put( "sup", //$NON-NLS-1$
				new StyleProcessor( ) {
					public void process( IStyle style )
					{
						style.setProperty( IStyle.STYLE_VERTICAL_ALIGN,
								IStyle.TOP_VALUE );
						style.setProperty( IStyle.STYLE_FONT_SIZE,
								createPercentageValue( 75 ) );
					}
				} );
		tag2Style.put( "big", //$NON-NLS-1$
				new StyleProcessor( ) {
					public void process( IStyle style )
					{
						style.setProperty( IStyle.STYLE_FONT_SIZE,
								createPercentageValue( 200 ) );
					}
				} );
		tag2Style.put( "small", //$NON-NLS-1$
				new StyleProcessor( ) {
					public void process( IStyle style )
					{
						style.setProperty( IStyle.STYLE_FONT_SIZE,
								createPercentageValue( 50 ) );
					}
				} );
		tag2Style.put( "tt", //$NON-NLS-1$
				new StyleProcessor( ) {
					public void process( IStyle style )
					{
						setFontFamily( style, IStyle.MONOSPACE_VALUE );
					}
				} );
		tag2Style.put( "center", //$NON-NLS-1$
				new StyleProcessor( ) {
					public void process( IStyle style )
					{
						style.setProperty( IStyle.STYLE_TEXT_ALIGN,
								IStyle.CENTER_VALUE );
					}
				} );
		tag2Style.put( "i", //$NON-NLS-1$
				new StyleProcessor( ) {
					public void process( IStyle style )
					{
						setFontStyle( style, IStyle.ITALIC_VALUE );
					}
				} );
		tag2Style.put( "address",
				new StyleProcessor( ) {
					public void process( IStyle style )
					{
						setFontStyle( style, IStyle.ITALIC_VALUE );
					}
				} );
		tag2Style.put( "ins",
				new StyleProcessor( ) {
					public void process( IStyle style )
					{
						style.setProperty( IStyle.STYLE_TEXT_UNDERLINE,
								IStyle.UNDERLINE_VALUE );
					}
				} );
		tag2Style.put( "strike",
				new StyleProcessor( ) {
					public void process( IStyle style )
					{
						style.setProperty( IStyle.STYLE_TEXT_LINETHROUGH,
								IStyle.LINE_THROUGH_VALUE );
					}
				} );
		tag2Style.put( "s",
				new StyleProcessor( ) {
					public void process( IStyle style )
					{
						style.setProperty( IStyle.STYLE_TEXT_LINETHROUGH,
								IStyle.LINE_THROUGH_VALUE );
					}
				} );
		tag2Style.put( "b", //$NON-NLS-1$
				new StyleProcessor( ) {
					public void process( IStyle style )
					{
						setFontWeight( style, IStyle.BOLD_VALUE );
					}
				} );
		tag2Style.put( "p", //$NON-NLS-1$
				new StyleProcessor( ) {
					public void process( IStyle style )
					{
						setMarginTopAndBottom( style, 1.33f );
					}
				} );
		tag2Style.put( "dl", //$NON-NLS-1$
				new StyleProcessor( ) {
					public void process( IStyle style )
					{
						setMarginTopAndBottom( style, 1.0f );
					}
				} );
		tag2Style.put( "u", //$NON-NLS-1$
				new StyleProcessor( ) {
					public void process( IStyle style )
					{
						style.setProperty( IStyle.STYLE_TEXT_UNDERLINE,
								IStyle.UNDERLINE_VALUE );
					}
				} );
		tag2Style.put( "del", //$NON-NLS-1$
				new StyleProcessor( ) {
					public void process( IStyle style )
					{
						style.setProperty( IStyle.STYLE_TEXT_LINETHROUGH,
								IStyle.LINE_THROUGH_VALUE );
					}
				} );
	}

	public static StyleProcessor getStyleProcess( String tagName )
	{
		return (StyleProcessor) tag2Style.get( tagName );
	}

	public static FloatValue createEmValue( float value )
	{
		return createFloatValue( CSSPrimitiveValue.CSS_EMS, value );
	}

	public static FloatValue createPercentageValue( float value )
	{
		return createFloatValue( CSSPrimitiveValue.CSS_PERCENTAGE, value );
	}

	private static FloatValue createFloatValue( short unitType, float value )
	{
		return new FloatValue( unitType, value );
	}
}
