/**
 *#########################################################################
 *
 * 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.
 *
 * Author: John Thompson, Greenstone Digital Library, University of Waikato
 *
 * Copyright (C) 1999 New Zealand Digital Library Project
 *
 * 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.
 *
* 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.
 *
 * 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.cdm;

import java.awt.*;
import java.io.*;
import java.util.*;
import javax.swing.*;
import javax.swing.event.*;
import org.greenstone.gatherer.Configuration;
import org.greenstone.gatherer.DebugStream;
import org.greenstone.gatherer.Gatherer;
import org.greenstone.gatherer.collection.BasicCollectionConfiguration;
import org.greenstone.gatherer.collection.CollectionManager;
import org.greenstone.gatherer.util.CheckList;
import org.greenstone.gatherer.util.CheckListEntry;
import org.greenstone.gatherer.util.StaticStrings;
import org.greenstone.gatherer.util.Utility;
import org.greenstone.gatherer.gui.DesignPaneHeader;
import org.greenstone.gatherer.Dictionary;
import org.w3c.dom.*;

/** This class contains the information about what supercollection has been specified (if any) and methods for changing this information. Note that there is a major difference between this manager and the others in that its DOM model is never used directly in any list component. It is only used to decide whether a certain entry in the actual checklist is checked. */
public class SuperCollectionManager
    extends DOMProxyListModel {

    static final public String SUPERCOLLECTION_COMMAND = "supercollection";
    static final public String CCS_COMMAND = "ccs";
    private ArrayList collection_checklist_model = null; // Model used to actually populate list
    private Control controls = null;
    private DOMProxyListModel model = null;
    private String current_coll_name = null;
    private boolean superCollectionChanged = false;

    public SuperCollectionManager(Element supercollections_element) {
	super(supercollections_element, StaticStrings.COLLECTION_ELEMENT, new SuperCollection());
	DebugStream.println("SuperCollectionManager: " + getSize() + " supercollection members parsed.");
	this.model = this;
    }

    public void destroy() {
	if(controls != null) {
	    controls.destroy();
	    controls = null;
	}
	if(collection_checklist_model != null) {
	    collection_checklist_model.clear();
	    collection_checklist_model = null;
	}
    }

    private void addSuperCollection(SuperCollection supercollection) {
	if(!contains(supercollection)) {
	    add(getSize(), supercollection);
	}
    }

    /** Method to retrieve the control for this manager.
     * @return the Control for editing supercollection settings
     */
    public Control getControls() {
	if(controls == null) {
	    // Build controls
	    this.controls = new SuperCollectionControl();
	}
	return controls;
    }

    public SuperCollection getSuperCollection(String collection_name) {
	SuperCollection result = null;
	int size = getSize();
	for(int i = 0; result == null && i < size; i++) {
	    SuperCollection supercollection = (SuperCollection) getElementAt(i);
	    if(supercollection.getName().equals(collection_name)) {
		result = supercollection;
	    }
	    supercollection = null;
	}
	return result;
    }
    /** Called when the detail mode has changed which in turn may cause several design elements to be available/hidden
     * @param mode the new mode as an int
     */
    public void modeChanged(int mode) {

    }

    private void removeSuperCollection(SuperCollection supercollection) {
	if(contains(supercollection)) {
	    remove(supercollection);
	}
    }

    /** Provides controls for altering the SuperCollection settings. */
    private class SuperCollectionControl
	extends JPanel
	implements Control {

	private boolean init = true;
	private CheckList collection_checklist = null;

	SuperCollectionControl() {
	    super();
            this.setComponentOrientation(Dictionary.getOrientation());
	    // Creation
	    JPanel header_panel = new DesignPaneHeader("CDM.GUI.SuperCollection", "xcollectionsearching");

	    collection_checklist = new CheckList(false);
	    buildModel();
	    collection_checklist.setListData(collection_checklist_model);

	    JPanel collection_checklist_pane = new JPanel();
            collection_checklist_pane.setComponentOrientation(Dictionary.getOrientation());
	    collection_checklist_pane.setBorder(BorderFactory.createEmptyBorder(5,0,0,0));
	    collection_checklist_pane.setLayout(new BorderLayout());
	    collection_checklist_pane.add(new JScrollPane(collection_checklist), BorderLayout.CENTER);

	    setBorder(BorderFactory.createEmptyBorder(0,5,0,0));
	    setLayout(new BorderLayout());
	    add(header_panel, BorderLayout.NORTH);
	    add(collection_checklist_pane, BorderLayout.CENTER);
	}

	public void destroy() {
	}

	public void gainFocus() {
	}

	public void loseFocus() {
	    int super_collections_count = 0;
	    // Retrieve the current supercollections
	    ArrayList supercollections = children();
	    // Now iterate through the checklist, and for each checked box found ensure the Supercollection exists, and ensure its assigned. Remove any supercollections altered in this way from the temporary array list
	    // we ignore the current coll at the moment
	    int size = collection_checklist_model.size();
	    for(int i = 0; i < size; i++) {
		CheckListEntry entry = (CheckListEntry) collection_checklist_model.get(i);
		if(entry.isSelected()) {
		    String collection_name = (String) entry.getProperty();
		    if (!collection_name.equals(current_coll_name)) {
			SuperCollection supercollection = getSuperCollection(collection_name);
			// Create the supercollection element if necessary
			if(supercollection == null) {
			    Element supercollection_element = root.getOwnerDocument().createElement(StaticStrings.COLLECTION_ELEMENT);
			    supercollection = new SuperCollection(supercollection_element);
			    supercollection.setName(collection_name);
			    addSuperCollection(supercollection);
			}
			else {
			    supercollections.remove(supercollection);
			}
			supercollection.setAssigned(true);
			super_collections_count++;
		    }
		}
	    }
	    if (super_collections_count > 0) {
		// we have some super colls, add in the current collection
		SuperCollection supercollection = getSuperCollection(current_coll_name);
		// Create the supercollection element if necessary
		if(supercollection == null) {
		    Element supercollection_element = root.getOwnerDocument().createElement(StaticStrings.COLLECTION_ELEMENT);
		    supercollection = new SuperCollection(supercollection_element);
		    supercollection.setName(current_coll_name);
		    addSuperCollection(supercollection);
		}
		else {
		    supercollections.remove(supercollection);
		}
		model.root.setAttribute(StaticStrings.ASSIGNED_ATTRIBUTE, StaticStrings.TRUE_STR);
	    } else {
		// current collection is the only one - don't bother adding it, because assigned is false, and we don't want to update the config file for an unassigned item.
		model.root.setAttribute(StaticStrings.ASSIGNED_ATTRIBUTE, StaticStrings.FALSE_STR);
	    }
	    
	    // Any collections left in the temporary list have been unselected, so delete them
	    for(int j = supercollections.size(); j > 0; j--) {
		SuperCollection supercollection = (SuperCollection) supercollections.get(j - 1);
		removeSuperCollection(supercollection);
	    }
	}

	
      private void buildModel()
      {
	collection_checklist_model = new ArrayList();
	current_coll_name = CollectionManager.getLoadedCollectionName(true);
	File collect_directory = new File(Gatherer.getCollectDirectoryPath());
	add_collections_to_model(collect_directory);
      }

      private void add_collections_to_model(File collect_directory) {
	File[] possible_collections = collect_directory.listFiles();
	for(int i = 0; possible_collections != null && i < possible_collections.length; i++) {
	  String file_name = (Gatherer.GS3)? Utility.CONFIG_GS3_FILE : Utility.CONFIG_FILE;
	  File collect_cfg_file = new File(possible_collections[i], file_name);
	  if (collect_cfg_file.exists()) {
	    BasicCollectionConfiguration collect_cfg = new BasicCollectionConfiguration(collect_cfg_file);
	    // look to see if group set?
	    // => if it is, don't add, but recurse to look for child collections in collect-group
	    if (collect_cfg.getCollectGroup().equals("true")) {
	      add_collections_to_model(possible_collections[i]);
	    } else {
	      // its a collection
	      StringBuffer title_buffer = new StringBuffer(collect_cfg.getName());
	      title_buffer.append(StaticStrings.SPACE_CHARACTER);
	      title_buffer.append(StaticStrings.LBRACKET_CHARACTER);
	      title_buffer.append(collect_cfg.getShortName());
	      title_buffer.append(StaticStrings.RBRACKET_CHARACTER);
	      String collection_title = title_buffer.toString();
	      title_buffer = null;
	      String collection_name = collect_cfg.getShortName();
	      // We have to block the model collection.
	      if (collect_cfg.getName().equals("**title**")) {
		continue;
	      }

	      // The current collection is always selected.
	      CheckListEntry entry = new CheckListEntry(collection_title);
	      entry.setProperty(collection_name);
	      entry.setSelected(getSuperCollection(collection_name) != null || collection_name.equals(current_coll_name));
	      entry.setFixed(collection_name.equals(current_coll_name));
	      collection_checklist_model.add(entry);
	    }
	  }
	  
	}
      }
    }
}
