/*
 * Created on 2005-03-24
 *
 * TODO To change the template for this generated file go to
 * Window - Preferences - Java - Code Style - Code Templates
 */
package org.flexdock.perspective;



import java.io.Serializable;

import org.flexdock.docking.Dockable;
import org.flexdock.docking.DockingManager;
import org.flexdock.docking.DockingPort;
import org.flexdock.docking.state.DockingState;
import org.flexdock.docking.state.LayoutNode;
import org.flexdock.event.EventManager;
import org.flexdock.perspective.event.LayoutListener;
import org.flexdock.perspective.event.PerspectiveEvent;

/**
 * @author Mateusz Szczap
 */
public class Perspective implements Cloneable, Serializable {
    private String m_persistentId;
    private String m_perspectiveName;
    private Layout m_layout;
    private LayoutSequence m_initalSequence;


    public Perspective(String persistentId, String perspectiveName) {
        this(persistentId, perspectiveName, false);
    }

    /**
     * @param persistentId
     * @param perspectiveName
     * @param defaultMode
     * @throws IllegalArgumentException
     *             if {@code persistentId} or {@code perspectiveName} is
     *             {@code null}.
     */
    public Perspective(String persistentId, String perspectiveName, boolean defaultMode) {
        if (persistentId == null) throw new IllegalArgumentException("persistentId cannot be null");
        if (perspectiveName == null) throw new IllegalArgumentException("perspectiveName cannot be null");
        m_persistentId = persistentId;
        m_perspectiveName = perspectiveName;
        m_layout = new Layout();
    }

    public String getName() {
        return m_perspectiveName;
    }

    public String getPersistentId() {
        return m_persistentId;
    }

    public void addDockable(String dockableId) {
        getLayout().add(dockableId);
    }

    public boolean removeDockable(String dockableId) {
        return (getLayout().remove(dockableId) != null);
    }

    public Dockable getDockable(String dockableId) {
        return (Dockable) getLayout().getDockable(dockableId);
    }

    public void addLayoutListener(LayoutListener listener) {
        getLayout().addListener(listener);
    }

    public void removeLayoutListener(LayoutListener listener) {
        getLayout().removeListener(listener);
    }

    public Dockable[] getDockables() {
        return getLayout().getDockables();
    }

    public DockingState getDockingState(String dockable) {
        return getLayout().getDockingState(dockable, false);
    }

    public DockingState getDockingState(Dockable dockable) {
        return getLayout().getDockingState(dockable, false);
    }

    public DockingState getDockingState(String dockable, boolean load) {
        return getLayout().getDockingState(dockable, load);
    }

    public DockingState getDockingState(Dockable dockable, boolean load) {
        return getLayout().getDockingState(dockable, load);
    }

    public LayoutSequence getInitialSequence() {
        return getInitialSequence(false);
    }

    public LayoutSequence getInitialSequence(boolean create) {
        if(m_initalSequence==null && create)
            m_initalSequence = new LayoutSequence();
        return m_initalSequence;
    }

    public void setInitialSequence(LayoutSequence sequence) {
        m_initalSequence = sequence;
    }

    public Layout getLayout() {
        return m_layout;
    }

    public void setLayout(Layout layout) {
        m_layout = layout;
    }

    public void reset(DockingPort port) {
        if(m_initalSequence!=null) {
            m_initalSequence.apply(port);

            Layout layout = getLayout();
            if(layout!=null) {
                layout.update(m_initalSequence);
                EventManager.getInstance().dispatchEvent(new PerspectiveEvent(this, null, PerspectiveEvent.RESET));
            }
        }
    }

    public void load(DockingPort port) {
        Layout layout = getLayout();
        if(layout.isInitialized()) {
            layout.apply(port);
            EventManager.getInstance().dispatchEvent(new PerspectiveEvent(this, null, PerspectiveEvent.RESET));
        } else {
            reset(port);
        }
    }

    public void unload() {
        Dockable[] dockables = getLayout().getDockables();
        for(int i=0; i<dockables.length; i++) {
            DockingManager.close(dockables[i]);
        }
    }

    public void cacheLayoutState(DockingPort port) {
        if(port!=null) {
            Layout layout = getLayout();
            LayoutNode node = port.exportLayout();
            layout.setRestorationLayout(node);
        }
    }

    public Object clone() {
        Perspective clone = new Perspective(m_persistentId, m_perspectiveName);
        clone.m_layout = (Layout)m_layout.clone();
        clone.m_initalSequence = m_initalSequence==null? null: (LayoutSequence)m_initalSequence.clone();
        return clone;
    }

}
