/*
 * (c) Copyright: Artenum SARL, 101-103 Boulevard Mac Donald,
 *                75019, Paris, France 2005.
 *                http://www.artenum.com
 *
 * License:
 *
 *  This program is free software; you can redistribute it
 *  and/or modify it under the terms of the Q Public License;
 *  either version 1 of the License.
 *
 *  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 Q Public License for more details.
 *
 *  You should have received a copy of the Q Public License
 *  License along with this program;
 *  if not, write to:
 *    Artenum SARL, 101-103 Boulevard Mac Donald,
 *    75019, PARIS, FRANCE, e-mail: contact@artenum.com
 */
package com.artenum.cassandra.pipeline;

import java.awt.Color;
import java.awt.Component;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;

import javax.swing.AbstractListModel;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.ListCellRenderer;

/**
 * <pre>
 * <b>Project ref           :</b> CASSANDRA project
 * <b>Copyright and license :</b> See relevant sections
 * <b>Status                :</b> under development
 * <b>Creation              :</b> 04/03/2005
 * <b>Modification          :</b>
 * 
 * <b>Description  :</b> A ListModel model made for VtkObjects
 * 
 * </pre>
 * <table cellpadding="3" cellspacing="0" border="1" width="100%">
 * <tr BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
 * <td><b>Version number</b></td>
 * <td><b>Author (name, e-mail)</b></td>
 * <td><b>Corrections/Modifications</b></td>
 * </tr>
 * <tr>
 * <td>0.1</td>
 * <td>Sebastien Jourdain, jourdain@artenum.com</td>
 * <td>Creation</td>
 * </tr>
 * </table>
 * 
 * @author Sebastien Jourdain, Artenum SARL
 * @author julien Forest, Artenum sARL
 * @version 0.1
 */
public class VtkObjectListModel extends AbstractListModel implements ListCellRenderer {
    private static final long serialVersionUID = -7207648389874912760L;
    private final ArrayList<CassandraObject> vtkObjectList;
    private final JLabel renderer;
    private Color selectedColor;
    private Color defaultColor;
    private final int modelType;
    private boolean showTypeError = false;

    public VtkObjectListModel(final int modelType) {
        this.vtkObjectList = new ArrayList<CassandraObject>();
        this.renderer = new JLabel();
        this.renderer.setOpaque(true);
        this.selectedColor = new Color(100, 100, 200);
        this.defaultColor = Color.white;
        this.modelType = modelType;
    }

    public void setPrefference(final Color selectedColor, final Color defaultColor, final boolean showTypeError) {
        if (selectedColor != null) {
            this.selectedColor = selectedColor;
        }

        if (defaultColor != null) {
            this.defaultColor = defaultColor;
        }

        this.showTypeError = showTypeError;
    }

    /**
     * returns the size of the Cassandra objects model list.
     */
    @Override
    public int getSize() {
        return this.vtkObjectList.size();
    }

    /**
     * return the Cassandra object stored in the pipeline manager at the given index.
     */
    @Override
    public Object getElementAt(final int index) {
        return this.vtkObjectList.get(index);
    }

    /**
     * Add a Cassandra object into the pipeline manager.
     * 
     * @param cassObject
     */
    public void addVtkObject(final CassandraObject cassObject) {
        if (cassObject.getType() == this.modelType) {
            this.vtkObjectList.add(cassObject);
            fireIntervalAdded(this, getSize() - 1, getSize() - 1);
        } else if (this.showTypeError) {
            System.err.println("Try to ADD invalide type in the VtkObjectListModel. (Expected: " + this.modelType
                    + " / Got: " + cassObject.getType() + ")");
        }
    }

    public void removeVtkObject(final CassandraObject vtkObject) {
        if (vtkObject.getType() == this.modelType) {
            final int index = this.vtkObjectList.indexOf(vtkObject);
            if (index != -1) {
                this.vtkObjectList.remove(index);
            }

            fireIntervalRemoved(this, index, index);
        } else if (this.showTypeError) {
            System.err.println("Try to REMOVE invalide type in the VtkObjectListModel. (Expected: " + this.modelType
                    + " / Got: " + vtkObject.getType() + ")");
        }
    }

    public CassandraObject getVtkObject(final int index) {
        return ((CassandraObject) getElementAt(index));
    }

    public CassandraObject getVtkObject(final Object encapsulateObject) {
        CassandraObject currentObject;
        for (final Iterator<CassandraObject> i = this.vtkObjectList.iterator(); i.hasNext();) {
            currentObject = i.next();
            if (currentObject.getVtkObject().equals(encapsulateObject)) {
                return currentObject;
            }
        }

        return null;
    }

    /**
     * Return the index of the given vtkObject in the refereed list or -1
     * if the object is not in the list. 
     * 
     * @param vtkObject
     * @return - index of the given vtkObject in the refereed list or -1
     * if the object is not in the list.
     */
    public int getVtkObjectIndex(final CassandraObject vtkObject) {
        return this.vtkObjectList.indexOf(vtkObject);
    }

    /**
     * return the last vtkObject loaded into the pipeine manager. 
     * @return
     */
    public CassandraObject getLastVtkObject() {
        return getVtkObject(getSize() - 1);
    }

    @Override
    public Component getListCellRendererComponent(final JList list, final Object value, final int index,
            final boolean isSelected, final boolean cellHasFocus) {
        this.renderer.setBackground(isSelected ? this.selectedColor : this.defaultColor);
        final CassandraObject vtkObject = (CassandraObject) value;
        this.renderer.setText(vtkObject.getName() + " (" + index + ")");
        return this.renderer;
    }

    public Collection<CassandraObject> getData() {
        return this.vtkObjectList;
    }
}
