##################################################################
## 
## 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.
##
################################################################## 
## Template to create the list of artefacts which are to be generated
##
## Documentation of template development can be found in local file
## TemplateHelp.html.
##
## Returns PuzzleComponent covering a PuzzlePiece or PuzzlePieceSet dependent if attribute is multiple times defined
#set($attribute = $model.getAttribute($context))
#set($NS = $attribute.getNamespace())
#set($localname = ${model.extractLocalname($attribute)})
#set($classname = "${model.camelCase($attribute)}Attribute")
#set ($valueobject = "String")
##
#set($datatypes = ${attribute.getDatatypes().withoutMultiples()})
#if ($datatypes.size() > 0)
#set ($hasdatatype = true)
#else
#set ($hasdatatype = false)
#end
##
##2DO: Svante - getValues() vs. getValueLiterals() - only literals / constants for attribute values are taken
#set($values = ${attribute.getValues().withoutMultiples()})
#if ($values.size() > 0)
#if ($values.size() ==2 && $hasdatatype == false)
#set ($trueFlag = false)
#set ($falseFlag = false)
#foreach ($value in $values)
#if ($value==true)
#set ($trueFlag = true)
#end
#if ($value==false)
#set ($falseFlag = true)
#end
#end
#if ($trueFlag and $falseFlag)
#set ($hasdatatype = true)
#set ($valueobject = "Boolean")
#end
#end
#set ($enum = true)
#if ($valueobject == "Boolean")
#set ($enum = false)
#end
#else
#set ($enum = false)
#end
##
## Check whether the attribute has default value.
##
#set ($hasDefaultValue = false)
#foreach ($parent in ${attribute.getParents().withoutMultiples()})
#if (${odfmodel.getDefaultAttributeValue($attribute, $parent)})
#set ($hasDefaultValue = true)
#end
#end
##
#set ($defaultValueSet = $odfmodel.getDefaultAttributeValues($attribute))
#if ($hasDefaultValue and $defaultValueSet.size() == 1)
#foreach ($value in $defaultValueSet)
#set ($uniqueDefaultValue = $value)
#end
#end
##
#include('copyright.txt')
/*
 * This file is automatically generated.
 * Don't edit manually.
 */
package org.odftoolkit.odfdom.dom.attribute.${NS};

import org.odftoolkit.odfdom.dom.OdfDocumentNamespace;
import org.odftoolkit.odfdom.pkg.OdfAttribute;
#if ($hasDefaultValue)
import org.odftoolkit.odfdom.pkg.OdfElement;
#end
import org.odftoolkit.odfdom.pkg.OdfFileDom;
import org.odftoolkit.odfdom.pkg.OdfName;

#if ($hasDefaultValue and $defaultValueSet.size()>1)
#foreach ($parent in ${attribute.getParents().withoutMultiples()})
#if ($odfmodel.getDefaultAttributeValue($attribute, $parent))
import org.odftoolkit.odfdom.dom.element.${parent.getNamespace()}.${model.camelCase($parent)}Element;
#end
#end
#end
/**
 * DOM implementation of OpenDocument attribute  {@odf.attribute ${attribute.getQName()}}.
 *
 */
public class $classname extends OdfAttribute {

	public static final OdfName ATTRIBUTE_NAME = OdfName.newName(OdfDocumentNamespace.${NS.toUpperCase()}, "$localname");
#if ($hasDefaultValue)
#if ($defaultValueSet.size()>1)
#foreach ($defaultValue in $defaultValueSet)
#set ($constant = $model.constantCase($defaultValue))
#if (($defaultValue=="true" or $defaultValue=="false") and $enum == false)
	public static final String DEFAULT_VALUE_${model.escapeKeyword($constant)} = "$defaultValue";
#else
	public static final String DEFAULT_VALUE_${model.escapeKeyword($constant)} = Value.${model.escapeKeyword($constant)}.toString();
#end
#end
#else
#if ($uniqueDefaultValue=="&#34;")
	public static final String DEFAULT_VALUE = "\${uniqueDefaultValue}";
#else
	public static final String DEFAULT_VALUE = "$uniqueDefaultValue";
#end
#end
#end

	/**
	 * Create the instance of OpenDocument attribute {@odf.attribute ${attribute}}.
	 *
	 * @param ownerDocument       The type is <code>OdfFileDom</code>
	 */
	public $classname(OdfFileDom ownerDocument) {
		super(ownerDocument, ATTRIBUTE_NAME);
	}

	/**
	 * Returns the attribute name.
	 *
	 * @return the <code>OdfName</code> for {@odf.attribute ${attribute}}.
	 */
	@Override
	public OdfName getOdfName() {
		return ATTRIBUTE_NAME;
	}

	/**
	 * @return Returns the name of this attribute.
	 */
	@Override
	public String getName() {
		return ATTRIBUTE_NAME.getLocalName();
	}
##
#if ($enum)

	/**
	 * The value set of {@odf.attribute ${attribute}}.
	 */
	public enum Value {
#set ($separator="		")
#foreach($value in $values)
#if (${value.toString().length()} == 1)
#set ($constant = $value)
#else
#set ($constant = $model.constantCase($value))
#end${separator}${model.escapeKeyword($constant)}("${model.escapeLiteral($value)}")#set ($separator=", ")
#end ;

		private String mValue;

		Value(String value) {
			mValue = value;
		}

		@Override
		public String toString() {
			return mValue;
		}

		public static Value enumValueOf(String value) {
			for(Value aIter : values()) {
				if (value.equals(aIter.toString())) {
				return aIter;
				}
			}
			return null;
		}
	}

	/**
	 * @param attrValue The <code>Enum</code> value of the attribute.
	 */
	public void setEnumValue(Value attrValue) {
		setValue(attrValue.toString());
	}

	/**
	 * @return Returns the <code>Enum</code> value of the attribute
	 */
	public Value getEnumValue() {
		return Value.enumValueOf(this.getValue());
	}
#end
##
## Handle Non-String-Attributes
#set ($valuetypes = ${javamodel.getValuetypes($datatypes)})
#if ($valueobject != "Boolean")
#foreach ($valuetype in $valuetypes)
#set ($valueobject = $valuetype)
#end
#end
#if ($valueobject != "String" && $valueobject != "Double" && $valueobject != "Integer" && $valueobject != "Boolean")
#set ($valueobject = "String")
#end
#if ($valueobject != "String")
#set ($simplevalue = ${javamodel.getPrimitiveType($valueobject)})
##

	/**
	 * @param value The <code>${simplevalue}</code> value of the attribute.
	 */
	public void set${model.camelCase($simplevalue)}Value(${simplevalue} value) {
		super.setValue(String.valueOf(value));
	}

	/**
	 * @return Returns the <code>${simplevalue}</code> value of the attribute
	 */
	public ${simplevalue} ${simplevalue}Value() {
		String val = super.getValue();
		try {
			return ${valueobject}.parse${model.camelCase($simplevalue)}(val);
		} catch (NumberFormatException e) {
			// TODO: validation handling/logging
			throw (e);
		}
	}
#end
##
#*
	/**
	 * @param attrValue The <code>String</code> value of the attribute.
	 * @throws IllegalArgumentException If the provided attribute value is invalid
	 */
	@Override
	public void setValue(String attrValue) {
#if ($enum)
#if ($hasdatatype)
## enum and datatype
		// Since we have not only enumValues, but also a DataType, we use String as common base and don't validate.
		super.setValue(attrValue);
#else
## enum and no datatype
		try {
			super.setValue(Value.enumValueOf(attrValue).toString());
		} catch (NullPointerException e) {
			throw new IllegalArgumentException(e);
		}
#end
#else
		try {
			super.setValue(attrValue);
		} catch (NullPointerException e) {
			// TODO: validation handling/logging
			throw new IllegalArgumentException(e);
		} catch (IllegalArgumentException e) {
			// TODO: validation handling/logging
			throw (e);
		}
#end
	}

	/**
	 * @return Returns the <code>String</code> value of the attribute
	 */
	@Override
	public String getValue() {
#if ($enum)
#if ($hasdatatype)
## enum and datatype
		// Since we have not only enumValues, but also a DataType, we use String as common base and don't validate.
		return super.getValue();
#else
## enum and no datatype
		try {
			return Value.enumValueOf(super.getValue()).toString();
		} catch (NullPointerException e) {
			throw new IllegalArgumentException("the value of ${attribute} is not valid");
		}
#end
#else
		try {
			return super.getValue();
		} catch (IllegalArgumentException e) {
			// TODO: validation handling/logging
			throw new NumberFormatException("the value of ${attribute} is not valid");
		}
#end
	}
*#
#if ($hasDefaultValue)
	/**
	 * Returns the default value of {@odf.attribute ${attribute}}.
	 *
	 * @return the default value as <code>String</code> dependent of its element name
	 *         return <code>null</code> if the default value does not exist
	 */
	@Override
	public String getDefault() {
		OdfElement parentElement = (OdfElement)getOwnerElement();
		String defaultValue = null;
		if (parentElement != null) {
#if ($defaultValueSet.size()>1)
#foreach ($parent in ${attribute.getParents().withoutMultiples()})
#if ($odfmodel.getDefaultAttributeValue($attribute, $parent))
			if (parentElement instanceof ${model.camelCase($parent)}Element) {
#set ($constant = ${model.constantCase($odfmodel.getDefaultAttributeValue($attribute, $parent))})
				defaultValue = DEFAULT_VALUE_${model.escapeKeyword($constant)};
			}
#end
#end
#else
			defaultValue=DEFAULT_VALUE;
#end
		}
		return defaultValue;
	}

	/**
	 * Default value indicator. As the attribute default value is dependent from its element, the attribute has only a default, when a parent element exists.
	 *
	 * @return <code>true</code> if {@odf.attribute ${attribute}} has an element parent
	 *         otherwise return <code>false</code> as undefined.
	 */
	@Override
	public boolean hasDefault() {
		return getOwnerElement() == null ? false : true;
	}
#else
	/**
	 * Returns the default value of {@odf.attribute ${attribute}}.
	 *
	 * @return the default value as <code>String</code> dependent of its element name
	 *         return <code>null</code> if the default value does not exist
	 */
	@Override
	public String getDefault() {
		return null;
	}

	/**
	 * Default value indicator. As the attribute default value is dependent from its element, the attribute has only a default, when a parent element exists.
	 *
	 * @return <code>true</code> if {@odf.attribute ${attribute}} has an element parent
	 *         otherwise return <code>false</code> as undefined.
	 */
	@Override
	public boolean hasDefault() {
		return false;
	}
#end

	/**
	 * @return Returns whether this attribute is known to be of type ID (i.e. xml:id ?)
	 */
	@Override
	public boolean isId() {
#if ($hasdatatype and $datatypes.size() > 0)
#set ($datatype="")
#foreach($value in $datatypes)
#set ($datatype=$value)
#end
#if ($datatype == "ID")
		return true;
#else
		return false;
#end
#else
		return false;
#end
	}
}
