/**
 *#########################################################################
 *
 * A component of the Gatherer application, part of the Greenstone digital
 * library suite from the New Zealand Digital Library Project at the
 * University of Waikato, New Zealand.
 *
 * <BR><BR>
 *
 * Author: Shaoqun Wu, Greenstone Digital Library, University of Waikato
 *
 * <BR><BR>
 *
 * Copyright (C) 2006 New Zealand Digital Library Project
 *
 * <BR><BR>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * <BR><BR>
 *
 * This program 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 General Public License for more details.
 *
 * <BR><BR>
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 *########################################################################
 */
package org.greenstone.gatherer.gems;

import org.apache.xerces.dom.*;// for new Documents
import org.w3c.dom.Document; 
import org.w3c.dom.DocumentType; 
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.Attr;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.NodeList;

import java.util.HashMap;
import java.util.ArrayList;

import org.greenstone.gatherer.util.XMLTools;

/**
 * @author Shaoqun Wu, Greenstone Digital Library, University of Waikato
 */
public class MetadataSetInfo
    extends AttributeContainer
{
 	
    private String file_path="";  

    private static ArrayList listeners = new ArrayList();  

    private static MetadataSetModel metadata_model;
       
    private String current_language = GEMSConstants.DEFAULT_LANGUAGE;

    private boolean isNew = false;

    public MetadataSetInfo(){       
	super(GEMSConstants.SET_REQUIRED_ATTRIBUTES, GEMSConstants.SET_LANG_DEPEND_ATTR_NAMES);
    } 

    public boolean isNamespaceAlreadyUsed(String namespace){
	if(metadata_model != null) {
	    return metadata_model.getMetadataSetManager().isNamespaceAlreadyUsed(namespace);
	}
	return false;
    }

    public void setNew(boolean isNew){
	this.isNew = isNew;
    }

    public boolean isNew(){
	return isNew;
    }
    
    public Document getMetadataSetDocument(){
	return  metadata_model.getMetadataSetDocument();
    }
    
    public MetadataSetModel getMetadataSetModel(){
        return metadata_model;
    } 
    
     public void setMetadataSetModel(MetadataSetModel model){
	 metadata_model = model;
     } 
    

    public String getMetadataSetName(){  
	return getMetadataSetName(getCurrentLanguage());
    }

    public String getMetadataSetName(String lang){    
        Attribute attr = getAttributeByNameAndLanguage(GEMSConstants.NAME_ATTRIBUTE,lang);
	if (attr != null) { 
	    return attr.getValue();
	}
	else {
	    return GEMSConstants.UNKNOWN_NAME;
	}      
    }

     public void setMetadataSetName(String name){ 
	 setMetadataSetName(name, getCurrentLanguage());
     }

    public void setMetadataSetName(String name,String lang){  
	Attribute attr =  getAttributeByNameAndLanguage(GEMSConstants.NAME_ATTRIBUTE,lang);
         if (attr != null){ 
	     attr.setValue(name);
	 } 
	 else {
	     attr = new Attribute(GEMSConstants.NAME_ATTRIBUTE, name, lang, true);
	     language_dependent_attributes.add(attr);    
	 }
    }


  
    public String getMetadataSetDescription(){  
	return getMetadataSetDescription(getCurrentLanguage());	 
    }
    
    public String getMetadataSetDescription(String lang){    
	Attribute attr = getAttributeByNameAndLanguage(GEMSConstants.DESCRIPTION_ATTRIBUTE,lang); 
	if (attr != null) { 
	    return attr.getValue();
	}
	else {
	    return "";
	}	 
    }
 
    public void setMetadataSetDescription(String desc) {
	setMetadataSetDescription(desc, getCurrentLanguage());
    }
    
    public void setMetadataSetDescription(String desc, String lang) {
	Attribute attr =  getAttributeByNameAndLanguage(GEMSConstants.DESCRIPTION_ATTRIBUTE,lang);
         if (attr != null){ 
	     attr.setValue(desc);
	 }
	 else {
	     attr = new Attribute(GEMSConstants.DESCRIPTION_ATTRIBUTE, desc, lang, true);
	     language_dependent_attributes.add(attr);    
	 }  
    }
    
    public String getCurrentLanguage(){
	return current_language;	
    }

    public void setCurrentLanguage(String lang){
	current_language = lang;	
    }
    
    public String getNamespace(){
      	Attribute attr = getAttributeByName(GEMSConstants.NAMESPACE_ATTRIBUTE); 
	if (attr != null){ 
	    return attr.getValue();
	 }
	else{
	    return "";
	 }       
    }
  
     public void setNamespace(String namespace){  
	Attribute attr =  getAttributeByName(GEMSConstants.NAMESPACE_ATTRIBUTE);
         if (attr != null){ 
	     attr.setValue(namespace);
	 }
	 else {
	     attr = new Attribute(GEMSConstants.NAMESPACE_ATTRIBUTE, namespace, true);
	     attributes.add(attr);
	 }    

    }

  
    public String getFilePath(){
	return file_path;
    }     
    
    
    public void infoChanged(){
	metadata_model.valueChanged();
    }
    
    public void setFilePath(String path){
        file_path = path;
    }     
    
    
    public void addMetadataSetListener(MetadataSetListener msl){
	if (!listeners.contains(msl))
	    listeners.add(msl);   
    }
    
    public void removeMetadataSetListener(MetadataSetListener msl){
        listeners.remove(msl);   
    }
     
    public void removeAllMetadataSetListeners(){
	  listeners.clear();
    }

    public void deleteMetadataSet(){
	metadata_model.getMetadataSetManager().deleteMetadataSet(this);

      	if (metadata_model.getMetadataSetInfo() != null 
	    && metadata_model.getMetadataSetInfo().getFilePath().equals(this.getFilePath())){
	    metadata_model.metadataSetDeleted();
	    MetadataSetEvent mse = new MetadataSetEvent(null);
	    for(int i=0;i<listeners.size();i++){
		MetadataSetListener msl = (MetadataSetListener) listeners.get(i);
		msl.metadataSetChanged(mse);          
	    }
	}
    }

    public void notifyListeners(){
        MetadataSetEvent mse = new MetadataSetEvent(this);
	for(int i=0;i<listeners.size();i++){
	    MetadataSetListener msl = (MetadataSetListener) listeners.get(i);
	    msl.metadataSetChanged(mse);          
	}
    }
 
    public void save(){
	Document doc = metadata_model.getMetadataSetDocument();

        //new metadata set
        if (doc == null){
	    doc = new DocumentImpl(); 
            DocumentType docType = new DocumentTypeImpl((DocumentImpl)doc,GEMSConstants.MATADATASET_NAME,null,GEMSConstants.SYSTEM_ID);                         
	    doc.appendChild(doc.createElement(GEMSConstants.METADATASET_ELEMENT));
	    doc.appendChild(docType);
	    metadata_model.setMetadataSetDocument(doc);          
	} 
    
        Element doc_element = doc.getDocumentElement(); 
	//remove all attributes
	NamedNodeMap attrs = doc.getDocumentElement().getAttributes();
	for (int i=0;i<attrs.getLength();i++){
	    Attr item = (Attr)attrs.item(i);
	    doc_element.removeAttribute(item.getName());
	}
       
	//add attributes
	for (int i=0;i<attributes.size();i++){
	    Attribute attr = (Attribute)attributes.get(i);
	    if (attr.getName() == null || attr.getName().trim().equals("")) continue;
            doc_element.setAttribute(attr.getName(),attr.getValue());
	}

        //remove all language dependent name and description elements
	NodeList setLanguages = doc_element.getElementsByTagName(GEMSConstants.SET_LANGUAGE_ELEMENT);  

	for (int i=setLanguages.getLength()-1;i>=0;--i){
	    Node set_language = setLanguages.item(i);
	    doc_element.removeChild(set_language);
	}

	 ArrayList names = XMLTools.getChildElementsByTagName(doc_element,GEMSConstants.NAME_ELEMENT);   
         for(int i=0;i< names.size();i++){
	     Element name_element = (Element)names.get(i);
	     doc_element.removeChild(name_element);
	 } 

        ArrayList deses = XMLTools.getChildElementsByTagName(doc_element,GEMSConstants.DESCRIPTION_ELEMENT);   
         for(int i=0;i< deses.size();i++){
	     Element des_element = (Element)deses.get(i);
	     doc_element.removeChild(des_element);
	 } 

	 Node first_child = doc_element.getFirstChild(); 

	 Node previous_element = null;

	 //add setLanguage elements
        ArrayList langs = getAllLanguages();
	for (int i=0;i<langs.size();i++){
	    String lang = (String)langs.get(i);
	    Attribute name = getAttributeByNameAndLanguage(GEMSConstants.NAME_ATTRIBUTE,lang);
	    if (name !=null){
		Element set_element = doc.createElement(GEMSConstants.SET_LANGUAGE_ELEMENT); 
		set_element.setAttribute(GEMSConstants.CODE_ATTRIBUTE,lang);
		Element name_element = doc.createElement(GEMSConstants.NAME_ELEMENT);
                name_element.appendChild(doc.createTextNode(name.getValue()));
		set_element.appendChild(name_element); 
               	Attribute des = getAttributeByNameAndLanguage(GEMSConstants.DESCRIPTION_ATTRIBUTE,lang);
                 if (des !=null){
		     Element des_element = doc.createElement(GEMSConstants.DESCRIPTION_ELEMENT);
		     des_element.appendChild(doc.createTextNode(des.getValue()));
		     set_element.appendChild(des_element);
		 }	 

		 if (first_child == null){
		    
		     if (previous_element !=null && previous_element.getNextSibling() !=null){ 
                         doc_element.insertBefore(set_element,previous_element.getNextSibling());  
		     }
		      else{
			  doc_element.appendChild(set_element);
		      }
		 }
		 else {
		     doc_element.insertBefore(set_element,first_child);
		     first_child = null;
		     previous_element = set_element;
		 }
	    }
	}

           
    }

 

}
