/**
 * Distributable under LGPL license.
 * See terms of license at gnu.org.
 *
 * Copyright (C)
 * <a href="http://www.inab.org">Spanish National Institute of Bioinformatics (INB)</a>
 * <a href="http://www.bsc.es">Barcelona Supercomputing Center (BSC)</a>
 * <a href="http://inb.bsc.es">Computational Node 6</a>
 */

package org.inb.biomoby.client.gui.ontology;

import java.awt.Dimension;
import java.util.List;
import javax.swing.BoxLayout;
import org.inb.biomoby.client.gui.auxiliary.AbstractAnnotationListPane.AnnotationListListener;
import org.inb.biomoby.client.gui.AbstractMobyComponent;
import org.inb.biomoby.client.gui.auxiliary.FeatureAnnotationListPane;
import org.inb.biomoby.client.gui.IDynamicComponent;
import org.inb.biomoby.client.gui.ISequenceCoordinateTransformer;
import org.inb.biomoby.client.gui.ISequenceDependent;
import org.inb.biomoby.client.gui.ITransformable;
import org.inb.biomoby.client.gui.ontology.CommentedAASequenceComponent.CommentedAASequenceListener;
import org.inb.biomoby.client.gui.ontology.FeatureAnnotatedAASequenceComponent.FeatureAnnotatedAASequenceListener;
import org.inb.biomoby.shared.datatypes.MobyInteger;
import org.inb.biomoby.shared.ontology.Annotation;
import org.inb.biomoby.shared.ontology.FeatureAnnotatedAASequence;

/**
 * @author Dmitry Repchevsky
 */

public class FeatureAnnotatedAASequenceComponent<T extends FeatureAnnotatedAASequence> extends AbstractMobyComponent<T>
        implements IDynamicComponent<FeatureAnnotatedAASequenceListener>,
                   ISequenceDependent,
                   ITransformable,
                   CommentedAASequenceListener,
                   AnnotationListListener
{
    private AnnotatedAASequenceComponent annotatedAASequencePanel;
    private FeatureAnnotationListPane annotations;

    private FeatureAnnotatedAASequenceComponent(AnnotatedAASequenceComponent annotatedAASequencePanel)
    {
        setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));

        add(annotatedAASequencePanel);

        annotatedAASequencePanel.addListener(this); // will proxy events

        annotations = new FeatureAnnotationListPane();
        annotations.setTransformer(annotatedAASequencePanel.getTransformer());

        annotations.addListener(this);

        add(annotations);

        this.annotatedAASequencePanel = annotatedAASequencePanel;
    }

    public FeatureAnnotatedAASequenceComponent()
    {
        this(new FeatureAnnotatedAASequence());
    }

    public FeatureAnnotatedAASequenceComponent(FeatureAnnotatedAASequence sequence)
    {
        this(new AnnotatedAASequenceComponent(sequence));

        annotations.setAnnotationList(sequence.getAnnotations());
    }

    @Override
    public void setPosition(int position)
    {
        annotatedAASequencePanel.setPosition(position);

        repaint();
    }

    @Override
    public void setSequenceVisible(boolean isVisible)
    {
        annotatedAASequencePanel.setSequenceVisible(isVisible);

        // if sequence is unvisible we can not transform annotations based on it...
        annotations.setTransformer(isVisible ? annotatedAASequencePanel.getTransformer() : null);
    }

    @Override
    public void setTransformer(ISequenceCoordinateTransformer transformer)
    {
        annotations.setTransformer(transformer);
    }

    @Override
    public ISequenceCoordinateTransformer getTransformer()
    {
        return annotations.getTransformer();
    }

    @Override
    public void positionChanged(int pos)
    {
        annotations.repaint();
    }

    @Override
    public void annotationsSelected(List<? extends Annotation> annotations)
    {
        if (!annotations.isEmpty())
        { // set position to the first annotation
            Annotation annotation = annotations.get(0);

            MobyInteger mobyInteger = annotation.getStart();

            if (mobyInteger != null)
            {
                final int position = mobyInteger.getInteger();
                setPosition(position);
            }
        }
    }

    @Override
    public Dimension getMaximumSize()
    {
        Dimension prf = this.getPreferredSize();
        Dimension max = super.getMaximumSize();

        return new Dimension(max.width, prf.height);
    }

    @Override
    public void addListener(MobyComponentListener listener)
    {
        annotatedAASequencePanel.addListener(listener);
        annotations.addListener(listener);
    }

    @Override
    public void removeListener(MobyComponentListener listener)
    {
        annotatedAASequencePanel.removeListener(listener);
        annotations.removeListener(listener);
    }

    public static interface FeatureAnnotatedAASequenceListener
            extends CommentedAASequenceListener, AnnotationListListener
    {

    }
}
