/**
 *#########################################################################
 *
 * 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.w3c.dom.Document;
import  org.w3c.dom.Element;
import org.greenstone.gatherer.util.XMLTools;

 
import java.util.Observable;
import java.util.ArrayList;

/**
 * @author Shaoqun Wu, Greenstone Digital Library, University of Waikato
 * @version 2.4
 */
public class MetadataSetModel 
    extends Observable implements MetadataSetListener, AttributeListener{

    private Document metadata_doc;

    private MetadataSetManager meta_manager;

    private ArrayList model;      

    private MetadataSetInfo meta_info;
    
    private boolean changed = false;


    //construt a new MetadataSet
    public MetadataSetModel(MetadataSetManager msm){
        meta_manager = msm;
	model = new ArrayList(); 
    }

    public String getCurrentLanguage(){
	return meta_manager.getCurrentLanguage();
    }

    public void metadataSetChanged(MetadataSetEvent mse){
	if (meta_info !=null) save(true); //save the last metadata set

	model = new ArrayList();
        meta_info = mse.getMetadataSetInfo();
	meta_info.setMetadataSetModel(this);
	metadata_doc = meta_manager.getMetadataSetDocument(meta_info.getFilePath());     
	
	constructModel();
    
        setChanged();
	notifyObservers();
	clearChanged();
     	changed = false;  
   
    } 

    public void valueChanged(){
        setChanged();
	notifyObservers(new Boolean(false));
	clearChanged();
    }
    

    private void constructModel(){
	if (metadata_doc == null) return;
	ArrayList elements =XMLTools.getChildElementsByTagName(metadata_doc.getDocumentElement(),GEMSConstants.ELEMENT_ELEMENT);
	for(int i=0;i<elements.size();i++){    
	    Element element = (Element)elements.get(i);     
	    model.add(new MetadataElementModel(element,meta_info));
	}                       
    }
    
    public boolean doesChildWithThisNameExist(String name) {
	for (int i=0; i<model.size(); i++) {
	    if (name.equals(((MetadataElementModel)model.get(i)).getName())) {
		return true;
	    }
	}
	return false;
    }

    public Document getMetadataSetDocument(){
	return metadata_doc;
    }

    public void setMetadataSetDocument(Document doc){
	metadata_doc = doc;
    }

    public MetadataSetManager getMetadataSetManager(){
	return meta_manager;
    } 
 
    public ArrayList getMetadataSetModel(){
	return model;
    }

    
    public void addChild(MetadataElementModel element_model){
	model.add(element_model);
	changed = true;
    }
    
    public void removeChild(MetadataElementModel element_model){
	model.remove(element_model);
	changed = true;
    }

   
    public void attributeChanged(AttributeEvent ae){      
    	changed = true;
    }
    
    public void setChanged(boolean ischanged){
	changed = ischanged;
    }

    public void save(boolean confirm){
	if ( meta_info == null || (!changed  && !meta_info.isNew())) return;

	meta_info.save();
	    
	if (metadata_doc !=null){
	    //remove all element elements
	    Element doc_element = metadata_doc.getDocumentElement();
	    ArrayList elements = XMLTools.getChildElementsByTagName(doc_element,GEMSConstants.ELEMENT_ELEMENT);   
	    for(int i=0;i< elements.size();i++){
		Element element = (Element)elements.get(i);
		doc_element.removeChild(element);
	    } 
	}

	for(int i=0;i< model.size();i++){
	    MetadataElementModel element_model = (MetadataElementModel)model.get(i);
            element_model.save();
	} 
	
	meta_manager.save(confirm);
	changed = false;
	
    }

    public MetadataSetInfo getMetadataSetInfo(){
	return meta_info; 
    } 

    public void metadataSetDeleted(){
	meta_info = null;
	setChanged();
	notifyObservers();
	clearChanged();
     	changed = false; 	

    }


    public boolean moveUp(MetadataElementModel child){
	int index = model.indexOf(child);
	if (index-1 >=0){
	    changed = true;
	    model.remove(child);
	    model.add(index-1,child);
	    return true;
	}        

	return false;
    }

    public boolean moveDown(MetadataElementModel child){
	int index = model.indexOf(child);
	if (index+1 < model.size()){
	    changed = true;
	    model.remove(child);
	    model.add(index+1,child);
	    return true;
	}        

	return false;
    }

}
