package org.eclipse.birt.report.tests.model.smoke;

import java.util.Iterator;
import java.util.Locale;

import junit.framework.Test;
import junit.framework.TestSuite;

import org.eclipse.birt.report.model.api.ColorHandle;
import org.eclipse.birt.report.model.api.DesignEngine;
import org.eclipse.birt.report.model.api.DimensionHandle;
import org.eclipse.birt.report.model.api.ElementFactory;
import org.eclipse.birt.report.model.api.FactoryPropertyHandle;
import org.eclipse.birt.report.model.api.FontHandle;
import org.eclipse.birt.report.model.api.HighlightRuleHandle;
import org.eclipse.birt.report.model.api.MapRuleHandle;
import org.eclipse.birt.report.model.api.ReportDesignHandle;
import org.eclipse.birt.report.model.api.SessionHandle;
import org.eclipse.birt.report.model.api.StyleHandle;
import org.eclipse.birt.report.model.api.activity.SemanticException;
import org.eclipse.birt.report.model.api.elements.DesignChoiceConstants;
import org.eclipse.birt.report.model.api.metadata.PropertyValueException;
import org.eclipse.birt.report.model.elements.ReportDesign;
import org.eclipse.birt.report.model.elements.Style;
import org.eclipse.birt.report.model.elements.interfaces.IStyleModel;
import org.eclipse.birt.report.tests.model.BaseTestCase;

import com.ibm.icu.util.ULocale;

public class StyleBuilderTest extends BaseTestCase
{

	public StyleBuilderTest(String name) {
		super(name);
		// TODO Auto-generated constructor stub
	}
	 public static Test suite()
	    {
			
			return new TestSuite(StyleBuilderTest.class);
		}
		protected void setUp( ) throws Exception
		{
			super.setUp( );
			openDesign( "StyleBuilderTest.xml" ); //$NON-NLS-1$
		}
		public void testStyleProperties( ) throws SemanticException
		{
			StyleHandle styleHandle = designHandle.findStyle( "My Style" ); //$NON-NLS-1$

			ColorHandle colorHandle = styleHandle.getColor( );
			colorHandle.setRGB( 0xFF0088 );
			assertEquals( 0xFF0088, colorHandle.getRGB( ) );

			// background

			colorHandle = styleHandle.getBackgroundColor( );
			assertNotNull( colorHandle );
			colorHandle.setStringValue( "red" ); //$NON-NLS-1$
			assertEquals( "red", colorHandle.getValue( ) ); //$NON-NLS-1$

			styleHandle.setBackgroundImage( "image1" ); //$NON-NLS-1$
			assertEquals( "image1", styleHandle.getBackgroundImage( ) ); //$NON-NLS-1$

			styleHandle
					.setBackgroundRepeat( DesignChoiceConstants.BACKGROUND_REPEAT_NO_REPEAT );
			assertEquals( DesignChoiceConstants.BACKGROUND_REPEAT_NO_REPEAT,
					styleHandle.getBackgroundRepeat( ) );

			styleHandle
					.setBackgroundAttachment( DesignChoiceConstants.BACKGROUND_ATTACHMENT_FIXED );
			assertEquals( DesignChoiceConstants.BACKGROUND_ATTACHMENT_FIXED,
					styleHandle.getBackgroundAttachment( ) );

			DimensionHandle dimensionHandle = styleHandle.getBackGroundPositionX( );
			dimensionHandle = styleHandle.getBackGroundPositionY( );

			// border color

			colorHandle = styleHandle.getBorderBottomColor( );
			try
			{
				colorHandle.setStringValue( "nocolor" ); //$NON-NLS-1$ 
				fail( );
			}
			catch ( PropertyValueException e )
			{
				assertEquals( e.getErrorCode( ),
						PropertyValueException.DESIGN_EXCEPTION_INVALID_VALUE );
			}

			colorHandle = styleHandle.getBorderLeftColor( );
			colorHandle.setRGB( 0x123456 );

			colorHandle = styleHandle.getBorderRightColor( );
			colorHandle.setRGB( 0x654321 );

			colorHandle = styleHandle.getBorderTopColor( );
			colorHandle.setStringValue( "yellow" ); //$NON-NLS-1$

			// border line style

			styleHandle
					.setBorderLeftStyle( DesignChoiceConstants.LINE_STYLE_DOTTED );
			assertEquals( DesignChoiceConstants.LINE_STYLE_DOTTED, styleHandle
					.getBorderLeftStyle( ) );
			styleHandle.setBorderRightStyle( DesignChoiceConstants.LINE_STYLE_NONE );
			assertEquals( DesignChoiceConstants.LINE_STYLE_NONE, styleHandle
					.getBorderRightStyle( ) );
			styleHandle.setBorderTopStyle( DesignChoiceConstants.LINE_STYLE_RIDGE );
			assertEquals( DesignChoiceConstants.LINE_STYLE_RIDGE, styleHandle
					.getBorderTopStyle( ) );
			styleHandle
					.setBorderBottomStyle( DesignChoiceConstants.LINE_STYLE_GROOVE );
			assertEquals( DesignChoiceConstants.LINE_STYLE_GROOVE, styleHandle
					.getBorderBottomStyle( ) );

			// invalid choice value

			try
			{
				styleHandle.setTextAlign( "nochoice" ); //$NON-NLS-1$ 
				fail( );
			}
			catch ( PropertyValueException e )
			{
				assertEquals( e.getErrorCode( ),
						PropertyValueException.DESIGN_EXCEPTION_CHOICE_NOT_FOUND );
			}

			// border width

			dimensionHandle = styleHandle.getBorderBottomWidth( );
			dimensionHandle
					.setStringValue( DesignChoiceConstants.LINE_WIDTH_MEDIUM );

			dimensionHandle = styleHandle.getBorderTopWidth( );
			dimensionHandle.setStringValue( "12pt" ); //$NON-NLS-1$

			dimensionHandle = styleHandle.getBorderLeftWidth( );
			dimensionHandle.setStringValue( "12mm" ); //$NON-NLS-1$

			dimensionHandle = styleHandle.getBorderRightWidth( );
			dimensionHandle.setStringValue( DesignChoiceConstants.LINE_WIDTH_THICK );

			dimensionHandle = styleHandle.getTextIndent( );
			dimensionHandle.setStringValue( "2pc" ); //$NON-NLS-1$

			// font properties

			FontHandle fontHandle = styleHandle.getFontFamilyHandle( );
			fontHandle.setStringValue( "song" ); //$NON-NLS-1$

			dimensionHandle = styleHandle.getFontSize( );
			dimensionHandle.setStringValue( "18pc" ); //$NON-NLS-1$

			styleHandle.setFontStyle( DesignChoiceConstants.FONT_STYLE_OBLIQUE );
			assertEquals( DesignChoiceConstants.FONT_STYLE_OBLIQUE, styleHandle
					.getFontStyle( ) );

			styleHandle
					.setFontVariant( DesignChoiceConstants.FONT_VARIANT_SMALL_CAPS );
			assertEquals( DesignChoiceConstants.FONT_VARIANT_SMALL_CAPS,
					styleHandle.getFontVariant( ) );

			styleHandle.setFontWeight( DesignChoiceConstants.FONT_WEIGHT_900 );
			assertEquals( DesignChoiceConstants.FONT_WEIGHT_900, styleHandle
					.getFontWeight( ) );

			// text properties

			dimensionHandle = styleHandle.getWordSpacing( );
			dimensionHandle.setStringValue( DesignChoiceConstants.NORMAL_NORMAL );

			dimensionHandle = styleHandle.getLetterSpacing( );
			dimensionHandle.setStringValue( "12pt" ); //$NON-NLS-1$

			styleHandle
					.setTextUnderline( DesignChoiceConstants.TEXT_UNDERLINE_NONE );
			assertEquals( DesignChoiceConstants.TEXT_UNDERLINE_NONE, styleHandle
					.getTextUnderline( ) );

			styleHandle
					.setTextOverline( DesignChoiceConstants.TEXT_OVERLINE_OVERLINE );
			assertEquals( DesignChoiceConstants.TEXT_OVERLINE_OVERLINE, styleHandle
					.getTextOverline( ) );

			styleHandle
					.setTextLineThrough( DesignChoiceConstants.TEXT_LINE_THROUGH_NONE );
			assertEquals( DesignChoiceConstants.TEXT_LINE_THROUGH_NONE, styleHandle
					.getTextLineThrough( ) );

			styleHandle
					.setVerticalAlign( DesignChoiceConstants.VERTICAL_ALIGN_SUPER );
			assertEquals( DesignChoiceConstants.VERTICAL_ALIGN_SUPER, styleHandle
					.getVerticalAlign( ) );

			styleHandle
					.setTextTransform( DesignChoiceConstants.TRANSFORM_CAPITALIZE );
			assertEquals( DesignChoiceConstants.TRANSFORM_CAPITALIZE, styleHandle
					.getTextTransform( ) );

			styleHandle.setTextAlign( DesignChoiceConstants.TEXT_ALIGN_RIGHT );
			assertEquals( DesignChoiceConstants.TEXT_ALIGN_RIGHT, styleHandle
					.getTextAlign( ) );

			styleHandle.setWhiteSpace( DesignChoiceConstants.WHITE_SPACE_NOWRAP );
			assertEquals( DesignChoiceConstants.WHITE_SPACE_NOWRAP, styleHandle
					.getWhiteSpace( ) );

			// box properties

			dimensionHandle = styleHandle.getMarginTop( );
			dimensionHandle.setStringValue( DesignChoiceConstants.MARGIN_AUTO );
			assertEquals( DesignChoiceConstants.MARGIN_AUTO, dimensionHandle
					.getStringValue( ) );

			dimensionHandle.setStringValue( "-9pt" ); //$NON-NLS-1$
			assertEquals("-9pt", dimensionHandle.getStringValue( ));
	

			// format

			try
			{
				styleHandle.setNumberFormatCategory( "#,###,###.##" ); //$NON-NLS-1$
				fail( );
			}
			catch ( PropertyValueException e )
			{
				assertEquals(
						PropertyValueException.DESIGN_EXCEPTION_CHOICE_NOT_FOUND, e
								.getErrorCode( ) );
			}

			styleHandle
					.setNumberFormatCategory( DesignChoiceConstants.NUMBER_FORMAT_TYPE_CURRENCY );
			styleHandle.setNumberFormat( "$##,##" ); //$NON-NLS-1$
			assertEquals( "$##,##", styleHandle.getNumberFormat( ) ); //$NON-NLS-1$

			styleHandle
					.setStringFormatCategory( DesignChoiceConstants.STRING_FORMAT_TYPE_LOWERCASE );
			styleHandle.setStringFormat( "***" ); //$NON-NLS-1$
			assertEquals( "***", styleHandle.getStringFormat( ) ); //$NON-NLS-1$		

			styleHandle
					.setDateTimeFormatCategory( DesignChoiceConstants.DATETIEM_FORMAT_TYPE_SHORT_DATE );
			styleHandle.setDateTimeFormat( "MM/DD/YYYY" ); //$NON-NLS-1$
			assertEquals( "MM/DD/YYYY", styleHandle.getDateTimeFormat( ) ); //$NON-NLS-1$		

			// section

			styleHandle.setDisplay( DesignChoiceConstants.DISPLAY_BLOCK );
			assertEquals( DesignChoiceConstants.DISPLAY_BLOCK, styleHandle
					.getDisplay( ) );

			// pagination

			styleHandle.setOrphans( DesignChoiceConstants.ORPHANS_INHERIT );
			assertEquals( DesignChoiceConstants.ORPHANS_INHERIT, styleHandle
					.getOrphans( ) );

			styleHandle.setWidows( "15" ); //$NON-NLS-1$

			assertEquals( "15", styleHandle.getWidows( ) ); //$NON-NLS-1$

			styleHandle.setPageBreakAfter( DesignChoiceConstants.PAGE_BREAK_AFTER_AVOID );
			assertEquals( DesignChoiceConstants.PAGE_BREAK_AFTER_AVOID, styleHandle
					.getPageBreakAfter( ) );

			styleHandle.setPageBreakBefore( DesignChoiceConstants.PAGE_BREAK_BEFORE_AVOID );
			assertEquals( DesignChoiceConstants.PAGE_BREAK_BEFORE_AVOID, styleHandle
					.getPageBreakBefore( ) );

			styleHandle
					.setPageBreakInside( DesignChoiceConstants.PAGE_BREAK_INSIDE_AVOID );
			assertEquals( DesignChoiceConstants.PAGE_BREAK_INSIDE_AVOID,
					styleHandle.getPageBreakInside( ) );

			styleHandle.setCanShrink( false );
			assertEquals( false, styleHandle.canShrink( ) );

			styleHandle.setShowIfBlank( false );
			assertEquals( false, styleHandle.showIfBlank( ) );

			styleHandle.setMapTestExpr( "new map rule test expr" ); //$NON-NLS-1$
			// assertEquals( "new map rule test expr", styleHandle.getMapTestExpr( )
			// ); //$NON-NLS-1$

			styleHandle.setHighlightTestExpr( "new highlight rule test expr" ); //$NON-NLS-1$
			// assertEquals(
			// "new highlight rule test expr", styleHandle.getHighlightTestExpr( )
			// ); //$NON-NLS-1$

			styleHandle.setMasterPage( "new master page" ); //$NON-NLS-1$
			assertEquals( "new master page", styleHandle.getMasterPage( ) ); //$NON-NLS-1$

			styleHandle.setStringFormat( "new string format" ); //$NON-NLS-1$
			assertEquals( "new string format", styleHandle.getStringFormat( ) ); //$NON-NLS-1$

			styleHandle.setBackgroundImage( "new background image" ); //$NON-NLS-1$
			assertEquals( "new background image", styleHandle.getBackgroundImage( ) ); //$NON-NLS-1$
		}

		/**
		 * Reads and sets values of properties of a highlight.
		 * 
		 * @throws SemanticException
		 *             if the value cannot be set properly
		 */

		public void testHighlightProperties( ) throws SemanticException
		{

			StyleHandle styleHandle = designHandle.findStyle( "My Style" ); //$NON-NLS-1$

			Iterator highlightHandles = styleHandle.highlightRulesIterator( );
			assertNotNull( highlightHandles );

			HighlightRuleHandle highlightHandle = (HighlightRuleHandle) highlightHandles
					.next( );
			ColorHandle colorHandle = highlightHandle.getColor( );
			colorHandle.setRGB( 0xFF0088 );

			colorHandle = highlightHandle.getBackgroundColor( );
			assertNotNull( colorHandle );
			colorHandle.setStringValue( "red" ); //$NON-NLS-1$

			colorHandle = highlightHandle.getBorderBottomColor( );
			try
			{
				colorHandle.setStringValue( "nocolor" ); //$NON-NLS-1$ 
				fail( );
			}
			catch ( PropertyValueException e )
			{
				assertEquals( e.getErrorCode( ),
						PropertyValueException.DESIGN_EXCEPTION_INVALID_VALUE );
			}

			colorHandle = highlightHandle.getBorderLeftColor( );
			colorHandle.setRGB( 0x123456 );

			colorHandle = highlightHandle.getBorderRightColor( );
			colorHandle.setRGB( 0x654321 );

			colorHandle = highlightHandle.getBorderTopColor( );
			colorHandle.setStringValue( "yellow" ); //$NON-NLS-1$

			highlightHandle
					.setBorderLeftStyle( DesignChoiceConstants.LINE_STYLE_DOTTED );
			highlightHandle
					.setBorderRightStyle( DesignChoiceConstants.LINE_STYLE_NONE );
			highlightHandle
					.setBorderTopStyle( DesignChoiceConstants.LINE_STYLE_RIDGE );
			highlightHandle
					.setBorderBottomStyle( DesignChoiceConstants.LINE_STYLE_GROOVE );

			assertEquals(DesignChoiceConstants.MAP_OPERATOR_BOTTOM_N,highlightHandle.getOperator());
			highlightHandle.setOperator( DesignChoiceConstants.MAP_OPERATOR_EQ );
			highlightHandle.setOperator( DesignChoiceConstants.MAP_OPERATOR_NE );
            highlightHandle.setOperator( DesignChoiceConstants.MAP_OPERATOR_TOP_N);
            
			highlightHandle.setValue1( "   dataSet.name  " ); //$NON-NLS-1$

			// No trim() for expression property type.
			assertEquals( "   dataSet.name  ", highlightHandle.getValue1( ) ); //$NON-NLS-1$

			// invalid choice value

			try
			{
				highlightHandle.setTextAlign( "nochoice" ); //$NON-NLS-1$ 
				fail( );
			}
			catch ( PropertyValueException e )
			{
				assertEquals( e.getErrorCode( ),
						PropertyValueException.DESIGN_EXCEPTION_CHOICE_NOT_FOUND );
			}

			highlightHandle.setTextAlign( DesignChoiceConstants.TEXT_ALIGN_JUSTIFY );
			highlightHandle
					.setTextLineThrough( DesignChoiceConstants.TEXT_LINE_THROUGH_NONE );

			highlightHandle
					.setTextOverline( DesignChoiceConstants.TEXT_OVERLINE_NONE );
			highlightHandle
					.setTextUnderline( DesignChoiceConstants.TEXT_UNDERLINE_NONE );
			highlightHandle
					.setTextTransform( DesignChoiceConstants.TRANSFORM_CAPITALIZE );

			highlightHandle
					.setNumberFormatCategory( DesignChoiceConstants.NUMBER_FORMAT_TYPE_CURRENCY );
			highlightHandle.setNumberFormat( "$000,000" ); //$NON-NLS-1$

			highlightHandle
					.setDateTimeFormatCategory( DesignChoiceConstants.DATETIEM_FORMAT_TYPE_MUDIUM_DATE );
			highlightHandle.setDateTimeFormat( "mm dd, yyyy" ); //$NON-NLS-1$

			highlightHandle
					.setStringFormatCategory( DesignChoiceConstants.STRING_FORMAT_TYPE_UPPERCASE );
			highlightHandle.setStringFormat( "no format" ); //$NON-NLS-1$

			try
			{
				highlightHandle.setStringFormatCategory( "no format" ); //$NON-NLS-1$
				fail( );
			}
			catch ( SemanticException e )
			{
				assertEquals(
						PropertyValueException.DESIGN_EXCEPTION_CHOICE_NOT_FOUND, e
								.getErrorCode( ) );
			}

			DimensionHandle dimensionHandle = highlightHandle
					.getBorderBottomWidth( );
			dimensionHandle
					.setStringValue( DesignChoiceConstants.LINE_WIDTH_MEDIUM );

			dimensionHandle = highlightHandle.getBorderTopWidth( );
			dimensionHandle.setStringValue( "12pt" ); //$NON-NLS-1$

			dimensionHandle = highlightHandle.getBorderLeftWidth( );
			dimensionHandle.setStringValue( "12mm" ); //$NON-NLS-1$

			dimensionHandle = highlightHandle.getBorderRightWidth( );
			dimensionHandle.setStringValue( DesignChoiceConstants.LINE_WIDTH_THICK );

			dimensionHandle = highlightHandle.getTextIndent( );
			dimensionHandle.setStringValue( "2pc" ); //$NON-NLS-1$

			FontHandle fontHandle = highlightHandle.getFontFamilyHandle( );
			fontHandle.setStringValue( "song" ); //$NON-NLS-1$

			dimensionHandle = highlightHandle.getFontSize( );
			dimensionHandle.setStringValue( "18pc" ); //$NON-NLS-1$

			highlightHandle.setFontStyle( DesignChoiceConstants.FONT_STYLE_OBLIQUE );
			highlightHandle
					.setFontVariant( DesignChoiceConstants.FONT_VARIANT_SMALL_CAPS );
			highlightHandle.setFontWeight( DesignChoiceConstants.FONT_WEIGHT_900 );

		}

		/**
		 * Reads and sets values of properties of a map rule.
		 * 
		 * @throws SemanticException
		 *             if the value cannot be set properly
		 */

		public void testMapRules( ) throws SemanticException
		{
			StyleHandle styleHandle = designHandle.findStyle( "My Style" ); //$NON-NLS-1$
			Iterator iter = styleHandle.mapRulesIterator( );

			MapRuleHandle ruleHandle = (MapRuleHandle) iter.next( );
			assertEquals( "Closed", ruleHandle.getDisplay( ) ); //$NON-NLS-1$
			assertNull( ruleHandle.getDisplayKey( ) );
			assertEquals( DesignChoiceConstants.MAP_OPERATOR_LIKE, ruleHandle
					.getOperator( ) );
			assertEquals( "X", ruleHandle.getValue1( ) ); //$NON-NLS-1$
			assertEquals( "Y", ruleHandle.getValue2( ) ); //$NON-NLS-1$

			ruleHandle.setDisplay( "new closed" ); //$NON-NLS-1$
			assertEquals( "new closed", ruleHandle.getDisplay( ) ); //$NON-NLS-1$

			ruleHandle.setDisplayKey( "new closed display id" ); //$NON-NLS-1$
			assertEquals( "new closed display id", ruleHandle.getDisplayKey( ) ); //$NON-NLS-1$

			ruleHandle.setOperator( DesignChoiceConstants.MAP_OPERATOR_LE );
			assertEquals( DesignChoiceConstants.MAP_OPERATOR_LE, ruleHandle
					.getOperator( ) );

			ruleHandle.setValue1( "new x" ); //$NON-NLS-1$
			ruleHandle.setValue2( "new y" ); //$NON-NLS-1$
			assertEquals( "new x", ruleHandle.getValue1( ) ); //$NON-NLS-1$
			assertEquals( "new y", ruleHandle.getValue2( ) ); //$NON-NLS-1$

			// to test parse the

			ruleHandle = (MapRuleHandle) iter.next( );
			assertEquals( "id for open", ruleHandle.getDisplayKey( ) ); //$NON-NLS-1$
		}

		public void testSetStyleFormat( ) throws Exception
		{
			designHandle = new SessionHandle( Locale.getDefault( ) ).createDesign( );
			design = (ReportDesign) designHandle.getModule();

			ElementFactory factory = new ElementFactory( design );
			StyleHandle style1 = factory.newStyle( "style1" ); //$NON-NLS-1$

			try
			{
				style1.setNumberFormatCategory( "no format" ); //$NON-NLS-1$
				fail( );
			}
			catch ( SemanticException e )
			{
				assertEquals(
						PropertyValueException.DESIGN_EXCEPTION_CHOICE_NOT_FOUND, e
								.getErrorCode( ) );
			}

			style1.setNumberFormat( "****" ); //$NON-NLS-1$
			style1
					.setNumberFormatCategory( DesignChoiceConstants.NUMBER_FORMAT_TYPE_FIXED );

			FactoryPropertyHandle factoryHandle = style1
					.getFactoryPropertyHandle( Style.NUMBER_FORMAT_PROP );

			assertEquals( "****", factoryHandle.getStringValue( ) ); //$NON-NLS-1$

		}

		public void testIsPredefinedStyle( )
		{

			SessionHandle sessionHandle = DesignEngine.newSession( ULocale.ENGLISH );
			ReportDesignHandle designHandle = sessionHandle.createDesign( );

			StyleHandle style = designHandle.getElementFactory( ).newStyle(
					"myStyle" ); //$NON-NLS-1$
			assertFalse( style.isPredefined( ) );

			style = designHandle.getElementFactory( ).newStyle( "grid" ); //$NON-NLS-1$
			assertTrue( style.isPredefined( ) );

			style = designHandle.getElementFactory( ).newStyle( "myStyle1" ); //$NON-NLS-1$
			assertFalse( style.isPredefined( ) );

		}

		public void testPropertyMask( )
		{
			SessionHandle sessionHandle = DesignEngine.newSession( ULocale.ENGLISH );
			ReportDesignHandle designHandle = sessionHandle.createDesign( );

			StyleHandle style = designHandle.getElementFactory( ).newStyle(
					"myStyle" ); //$NON-NLS-1$
			assertFalse( style.isPredefined( ) );

			try
			{
				style.setPropertyMask( IStyleModel.BACKGROUND_IMAGE_PROP,
						DesignChoiceConstants.PROPERTY_MASK_TYPE_LOCK );
				style.setBackgroundImage( "new url" ); //$NON-NLS-1$
				fail( );
			}
			catch ( SemanticException e )
			{
				assertEquals( PropertyValueException.DESIGN_EXCEPTION_VALUE_LOCKED,
						e.getErrorCode( ) );
			}
		}
	}
