/*
 * Copyright (C) 2007-2008 Esmertec AG.
 * Copyright (C) 2007-2008 The Android Open Source Project
 *
 * 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 com.android.mms.dom.smil;

import org.w3c.dom.DOMException;
import org.w3c.dom.smil.SMILDocument;
import org.w3c.dom.smil.SMILRegionElement;

import android.util.Log;

public class SmilRegionElementImpl extends SmilElementImpl implements
        SMILRegionElement {

    /*
     * Internal Interface
     */

    private static final String HIDDEN_ATTRIBUTE = "hidden";
    private static final String SLICE_ATTRIBUTE = "slice";
    private static final String SCROLL_ATTRIBUTE = "scroll";
    private static final String MEET_ATTRIBUTE = "meet";
    private static final String FILL_ATTRIBUTE = "fill";
    private static final String ID_ATTRIBUTE_NAME = "id";
    private static final String WIDTH_ATTRIBUTE_NAME = "width";
    private static final String TITLE_ATTRIBUTE_NAME = "title";
    private static final String HEIGHT_ATTRIBUTE_NAME = "height";
    private static final String BACKGROUND_COLOR_ATTRIBUTE_NAME = "backgroundColor";
    private static final String Z_INDEX_ATTRIBUTE_NAME = "z-index";
    private static final String TOP_ATTRIBUTE_NAME = "top";
    private static final String LEFT_ATTRIBUTE_NAME = "left";
    private static final String RIGHT_ATTRIBUTE_NAME = "right";
    private static final String BOTTOM_ATTRIBUTE_NAME = "bottom";
    private static final String FIT_ATTRIBUTE_NAME = "fit";
    private static final String TAG = "SmilRegionElementImpl";
    private static final boolean DEBUG = false;
    private static final boolean LOCAL_LOGV = false;

    SmilRegionElementImpl(SmilDocumentImpl owner, String tagName) {
        super(owner, tagName);
    }

    /*
     * SMILRegionElement Interface
     */

    public String getFit() {
        String fit = getAttribute(FIT_ATTRIBUTE_NAME);
        if (FILL_ATTRIBUTE.equalsIgnoreCase(fit)) {
            return FILL_ATTRIBUTE;
        } else if (MEET_ATTRIBUTE.equalsIgnoreCase(fit)) {
            return MEET_ATTRIBUTE;
        } else if (SCROLL_ATTRIBUTE.equalsIgnoreCase(fit)) {
            return SCROLL_ATTRIBUTE;
        } else if (SLICE_ATTRIBUTE.equalsIgnoreCase(fit)) {
            return SLICE_ATTRIBUTE;
        } else {
            return HIDDEN_ATTRIBUTE;
        }
    }

    public int getLeft() {
        try {
            return parseRegionLength(getAttribute(LEFT_ATTRIBUTE_NAME), true);
        } catch (NumberFormatException _) {
            if (LOCAL_LOGV) {
                Log.v(TAG, "Left attribute is not set or incorrect.");
            }
        }
        try {
            int bbw = ((SMILDocument) getOwnerDocument()).getLayout().getRootLayout().getWidth();
            int right = parseRegionLength(getAttribute(RIGHT_ATTRIBUTE_NAME), true);
            int width = parseRegionLength(getAttribute(WIDTH_ATTRIBUTE_NAME), true);
            return bbw - right - width;
        } catch (NumberFormatException _) {
            if (LOCAL_LOGV) {
                Log.v(TAG, "Right or width attribute is not set or incorrect.");
            }
        }
        return 0;
    }

    public int getTop() {
        try {
            return parseRegionLength(getAttribute(TOP_ATTRIBUTE_NAME), false);
        } catch (NumberFormatException _) {
            if (LOCAL_LOGV) {
                Log.v(TAG, "Top attribute is not set or incorrect.");
            }
        }
        try {
            int bbh = ((SMILDocument) getOwnerDocument()).getLayout().getRootLayout().getHeight();
            int bottom = parseRegionLength(getAttribute(BOTTOM_ATTRIBUTE_NAME), false);
            int height = parseRegionLength(getAttribute(HEIGHT_ATTRIBUTE_NAME), false);
            return bbh - bottom - height;
        } catch (NumberFormatException _) {
            if (LOCAL_LOGV) {
                Log.v(TAG, "Bottom or height attribute is not set or incorrect.");
            }
        }
        return 0;
    }

    public int getZIndex() {
        try {
            return Integer.parseInt(this.getAttribute(Z_INDEX_ATTRIBUTE_NAME));
        } catch (NumberFormatException _) {
            return 0;
        }
    }

    public void setFit(String fit) throws DOMException {
        if (fit.equalsIgnoreCase(FILL_ATTRIBUTE)
                || fit.equalsIgnoreCase(MEET_ATTRIBUTE)
                || fit.equalsIgnoreCase(SCROLL_ATTRIBUTE)
                || fit.equalsIgnoreCase(SLICE_ATTRIBUTE)) {
            this.setAttribute(FIT_ATTRIBUTE_NAME, fit.toLowerCase());
        } else {
            this.setAttribute(FIT_ATTRIBUTE_NAME, HIDDEN_ATTRIBUTE);
        }
    }

    public void setLeft(int left) throws DOMException {
        this.setAttribute(LEFT_ATTRIBUTE_NAME, String.valueOf(left));
    }

    public void setTop(int top) throws DOMException {
        this.setAttribute(TOP_ATTRIBUTE_NAME, String.valueOf(top));
    }

    public void setZIndex(int zIndex) throws DOMException {
        if (zIndex > 0) {
            this.setAttribute(Z_INDEX_ATTRIBUTE_NAME, Integer.toString(zIndex));
        } else {
            this.setAttribute(Z_INDEX_ATTRIBUTE_NAME, Integer.toString(0));
        }
    }

    public String getBackgroundColor() {
        return this.getAttribute(BACKGROUND_COLOR_ATTRIBUTE_NAME);
    }

    public int getHeight() {
        try {
            final int height = parseRegionLength(getAttribute(HEIGHT_ATTRIBUTE_NAME), false);
            return height == 0 ?
                    ((SMILDocument) getOwnerDocument()).getLayout().getRootLayout().getHeight() :
                        height;
        } catch (NumberFormatException _) {
            if (LOCAL_LOGV) {
                Log.v(TAG, "Height attribute is not set or incorrect.");
            }
        }
        int bbh = ((SMILDocument) getOwnerDocument()).getLayout().getRootLayout().getHeight();
        try {
            bbh -= parseRegionLength(getAttribute(TOP_ATTRIBUTE_NAME), false);
        } catch (NumberFormatException _) {
            if (LOCAL_LOGV) {
                Log.v(TAG, "Top attribute is not set or incorrect.");
            }
        }
        try {
            bbh -= parseRegionLength(getAttribute(BOTTOM_ATTRIBUTE_NAME), false);
        } catch (NumberFormatException _) {
            if (LOCAL_LOGV) {
                Log.v(TAG, "Bottom attribute is not set or incorrect.");
            }
        }
        return bbh;
    }

    public String getTitle() {
        return this.getAttribute(TITLE_ATTRIBUTE_NAME);
    }

    public int getWidth() {
        try {
            final int width = parseRegionLength(getAttribute(WIDTH_ATTRIBUTE_NAME), true);
            return width == 0 ?
                    ((SMILDocument) getOwnerDocument()).getLayout().getRootLayout().getWidth() :
                        width;
        } catch (NumberFormatException _) {
            if (LOCAL_LOGV) {
                Log.v(TAG, "Width attribute is not set or incorrect.");
            }
        }
        int bbw = ((SMILDocument) getOwnerDocument()).getLayout().getRootLayout().getWidth();
        try {
            bbw -= parseRegionLength(getAttribute(LEFT_ATTRIBUTE_NAME), true);
        } catch (NumberFormatException _) {
            if (LOCAL_LOGV) {
                Log.v(TAG, "Left attribute is not set or incorrect.");
            }
        }
        try {
            bbw -= parseRegionLength(getAttribute(RIGHT_ATTRIBUTE_NAME), true);
        } catch (NumberFormatException _) {
            if (LOCAL_LOGV) {
                Log.v(TAG, "Right attribute is not set or incorrect.");
            }
        }
        return bbw;
    }

    public void setBackgroundColor(String backgroundColor) throws DOMException {
        this.setAttribute(BACKGROUND_COLOR_ATTRIBUTE_NAME, backgroundColor);
    }

    public void setHeight(int height) throws DOMException {
        this.setAttribute(HEIGHT_ATTRIBUTE_NAME, String.valueOf(height) + "px");
    }

    public void setTitle(String title) throws DOMException {
        this.setAttribute(TITLE_ATTRIBUTE_NAME, title);
    }

    public void setWidth(int width) throws DOMException {
        this.setAttribute(WIDTH_ATTRIBUTE_NAME, String.valueOf(width) + "px");
    }

    /*
     * SMILElement Interface
     */

    @Override
    public String getId() {
        return this.getAttribute(ID_ATTRIBUTE_NAME);
    }

    @Override
    public void setId(String id) throws DOMException {
        this.setAttribute(ID_ATTRIBUTE_NAME, id);
    }

    /*
     * Internal Interface
     */

    private int parseRegionLength(String length, boolean horizontal) {
        if (length.endsWith("px")) {
            length = length.substring(0, length.indexOf("px"));
            return Integer.parseInt(length);
        } else if (length.endsWith("%")) {
            double value = 0.01*Integer.parseInt(length.substring(0, length.length() - 1));
            if (horizontal) {
                value *= ((SMILDocument) getOwnerDocument()).getLayout().getRootLayout().getWidth();
            } else {
                value *= ((SMILDocument) getOwnerDocument()).getLayout().getRootLayout().getHeight();
            }
            return (int) Math.round(value);
        } else {
            return Integer.parseInt(length);
        }
    }

    /*
     * (non-Javadoc)
     * @see java.lang.Object#toString()
     */
    @Override
    public String toString() {
        return super.toString()
                + ": id=" + getId()
                + ", width=" + getWidth()
                + ", height=" + getHeight()
                + ", left=" + getLeft()
                + ", top=" + getTop();
    }
}
