/*
 * Copyright 2006 IntelliME.
 *
 * Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.codecompany.plugins.intelliprof.diagram;

import com.intellij.openapi.graph.GraphManager;
import com.intellij.openapi.graph.builder.GraphBuilder;
import com.intellij.openapi.graph.builder.GraphDataModel;
import com.intellij.openapi.graph.layout.LayoutStage;
import com.intellij.openapi.graph.layout.orthogonal.DirectedOrthogonalLayouter;
import com.intellij.openapi.graph.settings.GraphSettingsProvider;
import com.intellij.openapi.graph.view.Graph2D;
import com.intellij.openapi.project.Project;
import org.jetbrains.annotations.NotNull;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

public class DiagramGraphDataModel extends GraphDataModel<UMLClass, UMLCall> {

    private List<UMLClass> umlClasses = new ArrayList<UMLClass>();
    private List<UMLCall> umlCalls = new ArrayList<UMLCall>();
    private GraphBuilder graphBuilder;
    private Project project;

    public DiagramGraphDataModel(Project project) {
        this.project = project;
    }

    public void setGraphBuilder(GraphBuilder graphBuilder) {
        this.graphBuilder = graphBuilder;
    }

    public Project getProject() {
        return project;
    }

    public UMLCall createEdge(UMLClass source, UMLClass target) {
        UMLCall umlCall = new UMLCall(source, target);
        umlCalls.add(umlCall);
        return umlCall;
    }

    @NotNull
    public String getEdgeName(UMLCall umlCall) {
        return umlCall.getName();
    }

    @NotNull
    public Collection<UMLCall> getEdges() {
        return umlCalls;
    }

    @NotNull
    public String getNodeName(UMLClass umlClass) {
        return umlClass.getName();
    }

    @NotNull
    public Collection<UMLClass> getNodes() {
        return umlClasses;
    }

    @NotNull
    public Collection<UMLCall> edgesFrom(UMLClass umlClass) {
        Collection collection = new ArrayList();
        for (UMLCall umlCall : umlCalls) {
            if (umlCall.getSource().equals(umlClass)) {
                collection.add(umlCall);
            }
        }

        return collection;
    }

    @NotNull
    public UMLClass getSourceNode(UMLCall umlCall) {
        return umlCall.getSource();
    }

    @NotNull
    public UMLClass getTargetNode(UMLCall umlCall) {
        return umlCall.getTarget();
    }

    public void dispose() {

    }

    public void doLayout() {
        if (graphBuilder != null) {
            Graph2D graph = graphBuilder.getGraph();

            //DirectedOrthogonalLayouter layouter = GraphSettingsProvider.getInstance(project)
            //        .getSettings(graph).getDirectedOrthogonalLayouter();

            /*
            DiagramLayouter layouter = new DiagramLayouter();

            if (graph.getNodeArray().length > 0 && layouter.canLayout(graph)) {
                GraphManager graphManager = GraphManager.getGraphManager();

                //graphManager.createBufferedLayouter(layouter).calcLayout(graph);
                graphManager.createBufferedLayouter(layouter).doLayout(graph);
                graph.updateViews();
            }
            */

            DiagramLayouter layouter = new DiagramLayouter();

            if (graph.getNodeArray().length > 0 && layouter.canLayout(graph)) {
                GraphManager graphManager = GraphManager.getGraphManager();
                layouter.doLayout(graph);

                graph.updateViews();
            }
        }
    }

    public void addNode(UMLClass umlClass) {
        //Graph graph = graphBuilder.getGraph();
        //com.intellij.openapi.graph.base.Node n =
        //        GraphWrapperUtil.getInstance(project).getNode(graph, umlClass);
//        if (graph.contains(n)) {
//            graph.removeNode(n);
//        }

        //net.sourceforge.intellime.ui.diagram.UMLCall e =
        //            util.getEdgeObject(graph, umlCalls.get(i));

        umlClasses.add(umlClass);
        update();
    }

    public void update() {
        if (graphBuilder != null) {
            graphBuilder.updateGraph();
        }
    }
}
