/*******************************************************************************
* Copyright (c)                                                                *
*           2005   Tristan Allwood,                                            *
*           2005   Daniel Burke,                                               *
*           2005   Marc Hull,                                                  *
*           2005   Ekaterina Itskova,                                          *
*           2005   Steve Zymler                                                *
*                                                                              *
* Permission is hereby granted, free of charge, to any person obtaining a      *
* copy of this software and associated documentation files (the                *
* "Software"), to deal in the Software without restriction, including          *
* without limitation the rights to use, copy, modify, merge, publish,          *
* distribute, sublicense, and/or sell copies of the Software, and to           *
* permit persons to whom the Software is furnished to do so, subject to        *
* the following conditions:                                                    *
*                                                                              *
* The above copyright notice and this permission notice shall be included      *
* in all copies or substantial portions of the Software.                       *
*                                                                              *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS      *
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF                   *
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.       *
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY         *
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,         *
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE            *
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                       *
*******************************************************************************/
/*
 * Created on 21-Oct-2004
 *
 */
package uk.ac.ic.doc.kevlar.api.programs.descriptions;

import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collection;

import org.w3c.dom.Element;
import org.w3c.dom.NodeList;

import uk.ac.ic.doc.kevlar.api.programs.XMLModelLoadingException;
import uk.ac.ic.doc.kevlar.publicInterfaces.IProgramDescription;
import uk.ac.ic.doc.kevlar.publicUtil.dom.XMLUtil;

/**
 * @author Daniel Burke
 *
 */
public final class ProgramDescriptionProvider {
	IProgramDescription description;

	/**
	 * @param descriptionModel XML data element for <description-model>
	 * @throws XMLModelLoadingException
	 */
	public ProgramDescriptionProvider(Element descriptionModel) throws XMLModelLoadingException
	{
	    try{
			String name = XMLUtil.yankText(descriptionModel, "name");
			String author = XMLUtil.yankText(descriptionModel, "author");
			
			URL website = null;
			try
			{
			    
			    String websiteText = XMLUtil.yankText(descriptionModel, "website");
			    if(websiteText != null)
			    {
			        website = new URL(websiteText);
			    }
			}
			catch(MalformedURLException r )
			{
			    throw new MalformedURLException(
			            "website's must be a valid fully qualified URL");
			}
			
			int majorVersion, minorVersion, copyrightYear;
			try
			{
			    majorVersion = Integer.parseInt(XMLUtil.yankText(descriptionModel, "version", "major"));
			    minorVersion = Integer.parseInt(XMLUtil.yankText(descriptionModel, "version", "minor"));
			}
			catch(NumberFormatException nfe)
			{
			    throw new NumberFormatException("major and minor version elements must contain numbers");
			}
	
			String copyrightOwner = XMLUtil.yankText(descriptionModel, "copyright", "name");
			
			try
			{
			    copyrightYear = 0;
			    
			    String copyrightYearText = XMLUtil.yankText(descriptionModel, "copyright", "year");
			    if(copyrightYearText != null)
			    {
			        copyrightYear = Integer.parseInt(copyrightYearText);
			    }
			}
			catch(NumberFormatException nfe)
			{
			    throw new NumberFormatException("copyright year elements must contain numbers");
			}
			
			String description = XMLUtil.yankText(descriptionModel, "description");
			String programHelp = XMLUtil.yankText(descriptionModel, "program-help");
			
			Collection<String> keywords = null;
			
			NodeList keywordsNodeList = descriptionModel.getElementsByTagName("keywords");
			if(keywordsNodeList.getLength() != 0)
			{
				keywords =  new ArrayList<String>();
				
			    Element keywordElement = (Element)keywordsNodeList.item(0);
			    NodeList keywordNodeList = keywordElement.getElementsByTagName("keyword");
	
				for(Element keyword : XMLUtil.getElementIterator(keywordNodeList))
				{
					keywords.add(XMLUtil.getInnerContent(keyword));
				}
			}
			
			this.description = makeProgramDescription(
					name,
					author,
					website,
					majorVersion,
					minorVersion,
					copyrightOwner,
					copyrightYear,
					keywords,
					description,
					programHelp);
	    }
	    catch(Exception e)
	    {
	        throw new XMLModelLoadingException(e);
	    }
	}
	
	public ProgramDescriptionProvider(IProgramDescription description)
	{
		if(! (description instanceof ProgramDescription))
		{
			throw new IllegalArgumentException("description must be actually a ProgramDescription");
		}
		
		this.description = description;
	}
	
	
	
	public IProgramDescription getProgramDescription()
	{
		return description;
	}
	
	public static IProgramDescription makeProgramDescription(
			String name,
			String author,
			URL website,
			int majorVersion,
			int minorVersion,
			String copyrightOwner,
			int copyrightYear,
			Collection<String> keywords,
			String description,
			String programHelp)
	{
		return new ProgramDescription(
			name,
			author,
			website,
			majorVersion,
			minorVersion,
			copyrightOwner,
			copyrightYear,
			keywords,
			description,
			programHelp);
	}
	
	public String toString()
	{
		return toString(0);
	}
	
	public String toString(int depth)
	{
		return description.toString(depth);
	}
}
