/*
 * Copyright 2011 Specto Technologies Inc. All rights reserved.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 */
package com.spectotechnologies.imageio.plugins.eps;

import org.w3c.dom.*;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import javax.imageio.metadata.IIOInvalidTreeException;
import javax.imageio.metadata.IIOMetadata;
import javax.imageio.metadata.IIOMetadataFormat;
import javax.imageio.metadata.IIOMetadataNode;

/**
 *
 * @author Specto Technologies Inc., Alexandre Lavoie
 */
public class EPSMetaData extends IIOMetadata
{
	static final boolean standardMetadataFormatSupported = false;
	static final String nativeMetadataFormatName = "com.spectotechnologies.imageio.plugins.eps.EPSMetaData_1.0";
	static final String nativeMetadataFormatClassName = "com.spectotechnologies.imageio.plugins.eps.EPSMetaData";
	static final String[] extraMetadataFormatNames = null;
	static final String[] extraMetadataFormatClassNames = null;

	// Keyword/value pairs
	List keywords = new ArrayList();
	List values = new ArrayList();

	public EPSMetaData()
	{
		super(standardMetadataFormatSupported,
			nativeMetadataFormatName,
			nativeMetadataFormatClassName,
			extraMetadataFormatNames,
			extraMetadataFormatClassNames);
	}

	@Override
	public IIOMetadataFormat getMetadataFormat(String formatName)
	{
		if(!formatName.equals(nativeMetadataFormatName))
		{
			throw new IllegalArgumentException("Bad format name!");
		}
		return EPSMetaDataFormat.getDefaultInstance();
	}

	@Override
	public Node getAsTree(String formatName)
	{
		if(!formatName.equals(nativeMetadataFormatName))
		{
			throw new IllegalArgumentException("Bad format name!");
		}

		// Create a root node
		IIOMetadataNode root = new IIOMetadataNode(nativeMetadataFormatName);

		// Add a child to the root node for each keyword/value pair
		Iterator keywordIter = keywords.iterator();
		Iterator valueIter = values.iterator();
		while(keywordIter.hasNext())
		{
			IIOMetadataNode node = new IIOMetadataNode("KeywordValuePair");
			node.setAttribute("keyword", (String)keywordIter.next());
			node.setAttribute("value", (String)valueIter.next());
			root.appendChild(node);
		}

		return root;
	}

	@Override
	public boolean isReadOnly()
	{
		return false;
	}

	@Override
	public void reset()
	{
		this.keywords = new ArrayList();
		this.values = new ArrayList();
	}

	@Override
	public void mergeTree(String formatName, Node root) throws IIOInvalidTreeException
	{
		if(!formatName.equals(nativeMetadataFormatName))
		{
			throw new IllegalArgumentException("Bad format name!");
		}

		Node node = root;

		if(!node.getNodeName().equals(nativeMetadataFormatName))
		{
			fatal(node, "Root must be " + nativeMetadataFormatName);
		}
		node = node.getFirstChild();
		while(node != null)
		{
			if(!node.getNodeName().equals("KeywordValuePair"))
			{
				fatal(node, "Node name not KeywordValuePair!");
			}

			NamedNodeMap attributes = node.getAttributes();
			Node keywordNode = attributes.getNamedItem("keyword");
			Node valueNode = attributes.getNamedItem("value");
			if (keywordNode == null || valueNode == null)
			{
				fatal(node, "Keyword or value missing!");
			}

			// Store keyword and value
			keywords.add((String)keywordNode.getNodeValue());
			values.add((String)valueNode.getNodeValue());

			// Move to the next sibling
			node = node.getNextSibling();
		}
	}

	private void fatal(Node node, String reason) throws IIOInvalidTreeException
	{
		throw new IIOInvalidTreeException(reason, node);
	}
}
