/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You 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.
 */

/* $Id$ */

package org.apache.xmlgraphics.xmp;

import java.net.URI;

import java.util.Iterator;
import java.util.Map;

import org.xml.sax.ContentHandler;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.AttributesImpl;

import org.apache.xmlgraphics.util.QName;
import org.apache.xmlgraphics.util.XMLizable;

/**
 * This class is the base class for all XMP properties.
 */
public class XMPProperty implements XMLizable {

    private QName name;
    private Object value;
    private String xmllang;
    private Map qualifiers;
    protected boolean attribute;

    /**
     * Creates a new XMP property.
     * @param name the name of the property
     * @param value the value for the property
     */
    public XMPProperty(QName name, Object value) {
        this.name = name;
        this.value = value;
    }

    /** @return the qualified name of the property (namespace URI + local name) */
    public QName getName() {
        return this.name;
    }

    /** @return the namespace URI of the property */
    public String getNamespace() {
        return getName().getNamespaceURI();
    }

    /**
     * Sets the value of the property
     * @param value the new value
     */
    public void setValue(Object value) {
        this.value = value;
    }

    /**
     * @return the property value (can be a normal Java object (normally a String) or a descendant
     *         of XMPComplexValue.
     */
    public Object getValue() {
        return this.value;
    }

    /**
     * Sets the xml:lang value for this property
     * @param lang the language ("x-default" for the default language, null to make the value
     *             language-independent)
     */
    public void setXMLLang(String lang) {
        this.xmllang = lang;
    }

    /**
     * @return the language for language-dependent values ("x-default" for the default language)
     */
    public String getXMLLang() {
        return this.xmllang;
    }

    /**
     * Indicates whether the property is an array.
     * @return true if the property is an array
     */
    public boolean isArray() {
        return value instanceof XMPArray;
    }

    /** @return the XMPArray for an array or null if the value is not an array. */
    public XMPArray getArrayValue() {
        return (isArray() ? (XMPArray)value : null);
    }

    /**
     * Converts a simple value to an array of a given type if the value is not already an array.
     * @param type the desired type of array
     * @return the array value
     */
    public XMPArray convertSimpleValueToArray(XMPArrayType type) {
        if (getArrayValue() == null) {
            XMPArray array = new XMPArray(type);
            if (getXMLLang() != null) {
                array.add(getValue().toString(), getXMLLang());
            } else {
                array.add(getValue());
            }
            setValue(array);
            setXMLLang(null);
            return array;
        } else {
            return getArrayValue();
        }
    }

    /** @return the XMPStructure for a structure or null if the value is not a structure. */
    public PropertyAccess getStructureValue() {
        return (value instanceof XMPStructure ? (XMPStructure)value : null);
    }

    private boolean hasPropertyQualifiers() {
        return (this.qualifiers == null) || (this.qualifiers.size() == 0);
    }

    /**
     * Indicates whether this property is actually not a structure, but a normal property with
     * property qualifiers. If this method returns true, this structure can be converted to
     * an simple XMPProperty using the simplify() method.
     * @return true if this property is a structure property with property qualifiers
     */
    public boolean isQualifiedProperty() {
        PropertyAccess props = getStructureValue();
        if (props != null) {
            XMPProperty rdfValue = props.getValueProperty();
            return (rdfValue != null);
        } else {
            return hasPropertyQualifiers();
        }
    }

    public void simplify() {
        PropertyAccess props = getStructureValue();
        if (props != null) {
            XMPProperty rdfValue = props.getValueProperty();
            if (rdfValue != null) {
                if (hasPropertyQualifiers()) {
                    throw new IllegalStateException("Illegal internal state"
                            + " (qualifiers present on non-simplified property)");
                }
                XMPProperty prop = new XMPProperty(getName(), rdfValue);
                Iterator iter = props.iterator();
                while (iter.hasNext()) {
                    QName name = (QName)iter.next();
                    if (!XMPConstants.RDF_VALUE.equals(name)) {
                        prop.setPropertyQualifier(name, props.getProperty(name));
                    }
                }
                props.setProperty(prop);
            }
        }
    }


    private void setPropertyQualifier(QName name, XMPProperty property) {
        if (this.qualifiers == null) {
            this.qualifiers = new java.util.HashMap();
        }
        this.qualifiers.put(name, property);
    }

    private String getEffectiveQName() {
        String prefix = getName().getPrefix();
        if (prefix == null || "".equals(prefix)) {
            XMPSchema schema = XMPSchemaRegistry.getInstance().getSchema(getNamespace());
            if (schema == null) {
                return getName().getLocalName();
            }
            prefix = schema.getPreferredPrefix();
        }
        return prefix + ":" + getName().getLocalName();
    }

    /** @see org.apache.xmlgraphics.util.XMLizable#toSAX(org.xml.sax.ContentHandler) */
    public void toSAX(ContentHandler handler) throws SAXException {
        AttributesImpl atts = new AttributesImpl();
        String qName = getEffectiveQName();
        if (value instanceof URI) {
            atts.addAttribute(XMPConstants.RDF_NAMESPACE, "resource", "rdf:resource", "CDATA", ((URI)value).toString());
        }
        handler.startElement(getName().getNamespaceURI(),
                getName().getLocalName(), qName, atts);
        if (value instanceof XMPComplexValue) {
            XMPComplexValue cv = ((XMPComplexValue)value);
            cv.toSAX(handler);
        } else if (!(value instanceof URI)) {
            char[] chars = value.toString().toCharArray();
            handler.characters(chars, 0, chars.length);
        }
        handler.endElement(getName().getNamespaceURI(),
                getName().getLocalName(), qName);
    }

    /** @see java.lang.Object#toString() */
    public String toString() {
        StringBuffer sb = new StringBuffer("XMP Property ");
        sb.append(getName()).append(": ");
        sb.append(getValue());
        return sb.toString();
    }

}
