/*
 * Copyright 2004-2005 The Trix Development Team.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.trix.cuery.property.css2;

import java.lang.reflect.Method;

import org.trix.cuery.property.CascadableProperty;
import org.trix.cuery.property.PropertyDefinition;
import org.trix.cuery.property.PropertyRegistry;
import org.trix.cuery.property.PropertyTestCase;
import org.trix.cuery.property.SimpleProperty;
import org.trix.cuery.property.config.FontConfiguration;
import org.trix.cuery.value.CSSPercentage;
import org.trix.cuery.value.CSSValue;
import org.trix.cuery.value.EMLength;
import org.trix.cuery.value.Identifier;
import org.trix.cuery.value.InchLength;
import org.trix.cuery.value.PixelLength;
import org.trix.cuery.value.PointLength;

/**
 * DOCUMENT.
 * 
 * @author <a href="mailto:Teletha.T@gmail.com">Teletha Testarossa</a>
 * @version $ Id: FontSizeDefinitionTest.java,v 1.0 2005/08/25 2:09:00 Teletha Exp $
 */
public class FontSizeDefinitionTest extends PropertyTestCase {

    /*
     * Test method for 'org.trix.cuery.property.FontSizeDefinition.FontSizeDefinition'
     */
    public void testFontSizeDefinitionEM() {
        // integer
        CSSValue value = new EMLength("2", null);
        CSSValue parent = new PointLength("2", null);
        assertEquals("4pt", getComputedValue("font-size", value, parent).getCssText());

        // decimal 20.47
        value = new EMLength("2.3", null);
        parent = new PointLength("8.9", null);
        assertEquals("20.5pt", getComputedValue("font-size", value, parent).getCssText());
    }

    /*
     * Test method for 'org.trix.cuery.property.FontSizeDefinition.FontSizeDefinition'
     */
    public void testFontSizeDefinitionPercentage() {
        // integer
        CSSValue value = new CSSPercentage("200", null);
        CSSValue parent = new PointLength("10", null);
        assertEquals("20pt", getComputedValue("font-size", value, parent).getCssText());

        // decimal 8.06
        value = new CSSPercentage("80.6", null);
        assertEquals("8.1pt", getComputedValue("font-size", value, parent).getCssText());
    }

    /*
     * Test method for 'org.trix.cuery.property.FontSizeDefinition.FontSizeDefinition'
     */
    public void testFontSizeDefinitionInch() {
        // integer
        CSSValue value = new InchLength("1", null);
        assertEquals("90px", getComputedValue("font-size", value, null).getCssText());

        // decimal
        value = new InchLength("0.1", null);
        assertEquals("9px", getComputedValue("font-size", value, null).getCssText());
    }

    /*
     * Test method for 'org.trix.cuery.property.FontSizeDefinition.FontSizeDefinition'
     */
    public void testFontSizeDefinitionPixel() {
        // integer
        CSSValue value = new PixelLength("10", null);
        assertEquals("10px", getComputedValue("font-size", value, null).getCssText());

        // decimal
        value = new PixelLength("10.3", null);
        assertEquals("10.3px", getComputedValue("font-size", value, null).getCssText());
    }

    private CSSValue getComputedValue(String propertyName, CSSValue value, CSSValue parent) {
        SimpleProperty property = new SimpleProperty();
        property.setProperty(propertyName, value, false);

        SimpleProperty parentProperty = new SimpleProperty();
        parentProperty.setProperty(propertyName, parent, false);

        PropertyDefinition definition = PropertyRegistry.getDefinition(propertyName);
        return definition.getComputedValue(value, property, parentProperty);
    }

    /*
     * Test method for 'org.trix.cuery.property.FontSizeDefinition.FontSizeDefinition'
     */
    public void testFontSizeDefinitionCascading() {
        // identifier
        CSSValue value = new Identifier("x-large", null);

        SimpleProperty property = new SimpleProperty();
        property.setProperty("font-size", value, false);

        CascadableProperty cascadable = new CascadableProperty();
        cascadable.addProperty(createDescription(property));

        assertEquals("17.3", cascadable.getValueAsString("font-size"));
    }

    /*
     * Test method for 'org.trix.cuery.property.FontSizeDefinition.getAbsoluteFontSize(String)'
     */
    public void testGetAbsoluteFontSize1() throws Exception {
        FontSizeDefinition definition = new FontSizeDefinition();
        Method method = definition.getClass().getDeclaredMethod("getAbsoluteFontSize", new Class[] {String.class});
        method.setAccessible(true);

        // 6.9444
        CSSValue value = (CSSValue) method.invoke(definition, new Object[] {"xx-small"});
        assertEquals("6.9px", value.getCssText());
        // 8.3333
        value = (CSSValue) method.invoke(definition, new Object[] {"x-small"});
        assertEquals("8.3px", value.getCssText());
        // 10
        value = (CSSValue) method.invoke(definition, new Object[] {"small"});
        assertEquals("10px", value.getCssText());
        // 12
        value = (CSSValue) method.invoke(definition, new Object[] {"medium"});
        assertEquals("12px", value.getCssText());
        // 14.4
        value = (CSSValue) method.invoke(definition, new Object[] {"large"});
        assertEquals("14.4px", value.getCssText());
        // 17.28
        value = (CSSValue) method.invoke(definition, new Object[] {"x-large"});
        assertEquals("17.3px", value.getCssText());
        // 20.736
        value = (CSSValue) method.invoke(definition, new Object[] {"xx-large"});
        assertEquals("20.7px", value.getCssText());
    }

    /*
     * Test method for 'org.trix.cuery.property.FontSizeDefinition.getAbsoluteFontSize(String)'
     */
    public void testGetAbsoluteFontSize2() throws Exception {
        PropertyRegistry.setFontConfiguration(new FontConfiguration() {

            /**
             * @see org.trix.cuery.property.config.FontConfiguration#getDisplayDPI()
             */
            public int getDisplayDPI() {
                return 72;
            }

            /**
             * @see org.trix.cuery.property.config.FontConfiguration#getLineHeightFactor()
             */
            public float getLineHeightFactor() {
                return 1.2f;
            }

            /**
             * @see org.trix.cuery.property.config.FontConfiguration#getMediumFontSize()
             */
            public float getMediumFontSize() {
                return 9.63f;
            }

            /**
             * @see org.trix.cuery.property.config.FontConfiguration#getScalingFactor()
             */
            public float getScalingFactor() {
                return 1.5f;
            }
        });

        FontSizeDefinition definition = new FontSizeDefinition();
        Method method = definition.getClass().getDeclaredMethod("getAbsoluteFontSize", new Class[] {String.class});
        method.setAccessible(true);

        // 2.853333...
        CSSValue value = (CSSValue) method.invoke(definition, new Object[] {"xx-small"});
        assertEquals("2.9px", value.getCssText());
        // 4.28
        value = (CSSValue) method.invoke(definition, new Object[] {"x-small"});
        assertEquals("4.3px", value.getCssText());
        // 6.42
        value = (CSSValue) method.invoke(definition, new Object[] {"small"});
        assertEquals("6.4px", value.getCssText());
        // 9.63
        value = (CSSValue) method.invoke(definition, new Object[] {"medium"});
        assertEquals("9.6px", value.getCssText());
        // 14.4
        value = (CSSValue) method.invoke(definition, new Object[] {"large"});
        assertEquals("14.4px", value.getCssText());
        // 21.6675
        value = (CSSValue) method.invoke(definition, new Object[] {"x-large"});
        assertEquals("21.7px", value.getCssText());
        // 32.50125
        value = (CSSValue) method.invoke(definition, new Object[] {"xx-large"});
        assertEquals("32.5px", value.getCssText());
    }
}
