/*
 * The contents of this file are subject to the Mozilla Public License
 * Version 1.1 (the "License");  you may not use this file except in 
 * compliance with the License.  You may obtain a copy of the License at
 * http://www.mozilla.org/MPL/
 *
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
 * the specific language governing rights and limitations under the License.
 *
 * The Original Code is Protege-2000.
 *
 * The Initial Developer of the Original Code is Stanford University. Portions
 * created by Stanford University are Copyright (C) 2007.  All Rights Reserved.
 *
 * Protege was developed by Stanford Medical Informatics
 * (http://www.smi.stanford.edu) at the Stanford University School of Medicine
 * with support from the National Library of Medicine, the National Science
 * Foundation, and the Defense Advanced Research Projects Agency.  Current
 * information about Protege can be obtained at http://protege.stanford.edu.
 *
 */

package edu.stanford.smi.protege.ui;

import java.awt.*;
import java.awt.datatransfer.*;
import java.util.*;

import javax.swing.*;

import edu.stanford.smi.protege.event.*;
import edu.stanford.smi.protege.model.*;
import edu.stanford.smi.protege.resource.*;
import edu.stanford.smi.protege.util.*;

/**
 * TODO Class Comment
 * 
 * @author Ray Fergerson <fergerson@smi.stanford.edu>
 */
public class DirectTypesList extends SelectableContainer {
    private SelectableList list;
    private Instance instance;
    private KnowledgeBase knowledgeBase;
    private AbstractAction addAction;

    private InstanceListener instanceListener = new InstanceListener() {

        public void directTypeAdded(InstanceEvent event) {
            ComponentUtilities.addListValue(list, event.getCls());
        }

        public void directTypeRemoved(InstanceEvent event) {
            ComponentUtilities.removeListValue(list, event.getCls());
        }

    };

    public DirectTypesList(Project project) {
        this.knowledgeBase = project.getKnowledgeBase();
        list = ComponentFactory.createSelectableList(null);
        list.setCellRenderer(new FrameRenderer());
        setSelectable(list);

        LabeledComponent c = new LabeledComponent("Types", new JScrollPane(list));
        c.addHeaderButton(createAddTypeAction());
        c.addHeaderButton(createRemoteTypeAction());
        setLayout(new BorderLayout());
        add(c);
        setPreferredSize(new Dimension(0, 100));

        list.setDragEnabled(true);
        list.setTransferHandler(new FrameTransferHandler());
    }

    private class FrameTransferHandler extends TransferHandler {
        protected Transferable createTransferable(JComponent c) {
            Collection collection = getSelection();
            return collection.isEmpty() ? null : new TransferableCollection(collection);
        }

        public boolean canImport(JComponent c, DataFlavor[] flavors) {
            return true;
        }

        public boolean importData(JComponent component, Transferable data) {
            return true;
        }

        protected void exportDone(JComponent source, Transferable data, int action) {
            if (action == MOVE) {
                Iterator i = getSelection().iterator();
                while (i.hasNext()) {
                    Cls type = (Cls) i.next();
                    int index = 0;
                    Log.getLogger().info("Move " + type + " to: " + index);
                    instance.moveDirectType(type, index);
                    updateModel();
                }
            }
        }

        public int getSourceActions(JComponent c) {
            return MOVE;
        }
    };

    public void setInstance(Instance newInstance) {
        if (instance != null) {
            instance.removeInstanceListener(instanceListener);
        }
        instance = newInstance;
        if (instance != null) {
            instance.addInstanceListener(instanceListener);
        }
        updateModel();
        updateAddButton();
    }

    public void updateModel() {
        ListModel model;
        if (instance == null) {
            model = new DefaultListModel();
        } else {
            Collection types = instance.getDirectTypes();
            model = new SimpleListModel(types);
        }
        list.setModel(model);
    }

    public void updateAddButton() {
        addAction.setEnabled(instance != null);
    }

    private Action createAddTypeAction() {
        addAction = new AddAction(ResourceKey.CLASS_ADD) {
            public void onAdd() {
                Collection clses = DisplayUtilities.pickClses(DirectTypesList.this, knowledgeBase);
                Iterator i = clses.iterator();
                while (i.hasNext()) {
                    Cls cls = (Cls) i.next();
                    if (!instance.hasType(cls)) {
                    	instance.addDirectType(cls);
                    }
                }
            }
        };
        return addAction;
    }

    private Action createRemoteTypeAction() {
        return new RemoveAction(ResourceKey.CLASS_REMOVE, list) {
            public void onRemove(Object o) {
                Cls cls = (Cls) o;
                instance.removeDirectType(cls);
            }
        };
    }
}