##################################################################
## 
## 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.
##
##
## Begin Code
#include('copyright.txt')
/*
 * This file is automatically generated.
 * Don't edit manually.
 */
package org.odftoolkit.odfdom.dom.style;

import java.util.Arrays;
import java.util.Collections;
import org.odftoolkit.odfdom.dom.style.props.OdfStyleProperty;
import java.util.Set;
import java.util.TreeSet;
import java.util.Map;
import java.util.HashMap;
##
#foreach ($styleelement in ${model.getElements().withoutMultiples()})
#if ($styleelement.getNamespace() == "style" && ${styleelement.getLocalName().endsWith("properties")})
import org.odftoolkit.odfdom.dom.element.style.${model.camelCase($styleelement)}Element;
#end
#end

public class OdfStyleFamily implements Comparable<OdfStyleFamily> {

	private Set<OdfStyleProperty> m_properties = new TreeSet<OdfStyleProperty>();
	private static Map<String, OdfStyleFamily> m_familyByName = new HashMap<String, OdfStyleFamily>();

	public static OdfStyleFamily getByName(String name) {
		return m_familyByName.get(name);
	}

	private OdfStyleFamily(String name, OdfStyleProperty[] props) {
		m_name = name;
		m_properties.addAll(Arrays.asList(props));
		m_familyByName.put(name, this);
	}

	private OdfStyleFamily(String name) {
		m_name = name;
		m_familyByName.put(name, this);
	}
		
	public String getName() {
		return m_name;
	}

	public int compareTo(OdfStyleFamily o) {
		return m_name.compareTo(o.toString());
	}

	public static OdfStyleFamily valueOf(String name) {
		OdfStyleFamily family = getByName(name);
		if (family == null) {
			family = new OdfStyleFamily(name);
		} 
		return family;
	}

	public static String toString(OdfStyleFamily family) {
		if (family != null) {
			return family.toString();
		}
		else {
			return new String();
		}
	}

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

	public Set<OdfStyleProperty> getProperties() {
		return Collections.unmodifiableSet(m_properties);
	}

#foreach ($family in ${odfmodel.getStyleFamilies()})
	public final static OdfStyleFamily ${model.camelCase($model.extractLocalname($family))} = new OdfStyleFamily("${model.extractLocalname($family)}",
			new OdfStyleProperty[]{
#foreach ($styleelement in ${model.getElements().withoutMultiples()})
#if ($styleelement.getNamespace() == "style" && ${styleelement.getLocalName().endsWith("properties")})
#foreach ($property in ${styleelement.withMultiples().getAttributes()})
#set($propertyName = ${property.getLocalName()})
#if (${styleelement.getLocalName()}=="graphic-properties" && $propertyName =="shadow")
#set($propertyName = ${property.getQName()})
#end
	${model.camelCase($styleelement)}Element.${model.camelCase($propertyName)},
#end
#end
#end
	});

#end
}
