package Algorithms.Animated.BK;

import java.util.ArrayList;

import Algorithms.Animated.AlgorithmStage;
import Algorithms.Animated.BackwardAction;
import Model.LayeredGraphEdge;
import Model.LayeredGraphNode;

public class ConflictDetection implements AlgorithmStage {

    private LayeredGraphNode graph;
    private ArrayList< BackwardAction > actions;
    
    private int i;
    private int l1;
    
    ConflictDetection( LayeredGraphNode graph )
    {
        this.graph = graph;
        actions = new ArrayList<>();
        i = 1;
        l1 = 0;
    }
    
    @Override
    public StageStatus forwardStep() {
    	int oldI = i;
    	int oldL1 = l1;
    	if( i + 1 >= graph.getContainedLayers().size() - 1 )
    		return StageStatus.FINISHED;
    	LayeredGraphNode curr = graph.getContainedLayers().get( i + 1 ).get( l1 );
    	curr.setSelected( null );
    	ArrayList< LayeredGraphEdge > edges = curr.getIncomingEdges();
    	LayeredGraphEdge dummyEdge = null;
    	for( LayeredGraphEdge e : edges )
    	{
    		if( e.isDummyEdge() )
    		{
    			dummyEdge = e;
    			break;
    		}
    	}
    	ArrayList< LayeredGraphEdge > conflicts = new ArrayList<>();
        if( dummyEdge != null )
        {
    		for( LayeredGraphEdge e : edges )
    		{
    			if( e.isDummyEdge() )
    			{
    				ArrayList< LayeredGraphEdge > conf = e.calcConflictedEdges();
    				for( LayeredGraphEdge ce : conf )
    				{
    					if( !ce.isDummyEdge() )
    						conflicts.add( ce );
    				}
    			}
    		}
        }
        for( LayeredGraphEdge c : conflicts )
        	c.setConflicted( true, null );
    	StageStatus status =  calcNextStatus();
    	actions.add( ()->{
    		i = oldI;
    		l1 = oldL1;
            for( LayeredGraphEdge c : conflicts )
            	c.setConflicted( false, null );
    	});
    	return status;
    }
    
    private StageStatus calcNextStatus()
    {
        l1++;
        if( l1 >= graph.getContainedLayers().get( i + 1 ).size() )
        {
            i++;
            if( i >= graph.getContainedLayers().size() - 2 )
            {
                i--;
                l1--;
                return StageStatus.FINISHED;
            }
            l1 = 0;
        }
        return StageStatus.UNFINISHED;
    }

    @Override
    public StageStatus backwardStep() {
        if( actions.size() == 0 )
        	return StageStatus.FINISHED;
        actions.get( 0 ).reverse();
        actions.remove( 0 );
        return StageStatus.UNFINISHED;
    }
}
