// Path: lib-algo/src/lse/math/games/lcp/LemkeAlgorithm.java
//   @SuppressWarnings("serial")
//   public static class RayTerminationException extends LemkeException {
// public Tableau A;
// public LCP start;
// 
// public RayTerminationException(String error, Tableau A, LCP start) 
// { 
// 	super(error);
// 	this.A = A;
// 	this.start = start;
// }
// 		
// @Override
// public String getMessage()
// {
// 	StringBuilder sb = new StringBuilder()
// 		.append(super.getMessage())
// 		.append(System.getProperty("line.separator"))
// 		.append(start != null ? start.toString() : "LCP is null")
// 		.append(System.getProperty("line.separator"))
// 		.append(A.toString());
// 	return sb.toString();
// }
//   }


import lse.math.games.lcp.LemkeAlgorithm.RayTerminationException;

package lse.math.games.lcp;


// This class seems specific to the representation of the Tableau?
// See if I can decouple from specifics of Tableau
// See if I can decouple from LCP specifics (read: z0leave)
//
// This class takes an var to enter the basis and determines which
// var should leave.
//
// This needs to be split into two parts, one part belongs in Lemke, the other in Tableau
public class LexicographicMethod
{
    public int[] tested;        //TODO: make private
    public int[] comparisons;   //TODO: make private  
    private int[] leavecand;    /* leavecand [0..numcand-1] = candidates (rows) for leaving var */ 
    private LCP start;

    public LexicographicMethod(int basisSize, LCP start)
    {
	this.start = start;
        leavecand = new int[basisSize];
        InitStatistics(basisSize + 1);
    }

    //region Minimum Leaving Variable
    private boolean z0leave;
    
    /**
     * z0leave
     * ==========================================================
     * @return the state of the z0leave boolean following the 
     * last call to minVar().  Indicates that z0 can leave the
     * basis, but the lex-minratio test is performed fully,
     * so the returned value might not be the index of  z0.
     */
    public boolean z0leave() { return z0leave; }

    /** 
     * minVar
     * ===========================================================
     * @return the leaving variable in  VARS, given by lexmin row, 
     * when  enter  in VARS is entering variable
     * only positive entries of entering column tested
     * boolean  *z0leave  indicates back that  z0  can leave the
     * basis, but the lex-minratio test is performed fully,
     * so the returned value might not be the index of  z0
     */
    public int lexminratio(Tableau A, int enter)
    	throws RayTerminationException
    {
        z0leave = false;                                                
        
        // TODO: I think I can comment for perf... (but a unit test will fail)
        // I could pass in a cobasic index instead
        A.vars().assertNotBasic(enter);
        int col = A.vars().col(enter);
                      
        int numcand = 0;
        for (int i = 0; i < leavecand.length; i++) {                    /* start with  leavecand = { i | A[i][col] > 0 } */
            if (A.isPositive(i, col)) {
                leavecand[numcand++] = i;
            }
        }


// Path: lib-algo/src/lse/math/games/lcp/LemkeAlgorithm.java
//   @SuppressWarnings("serial")
//   public static class RayTerminationException extends LemkeException {
// public Tableau A;
// public LCP start;
// 
// public RayTerminationException(String error, Tableau A, LCP start) 
// { 
// 	super(error);
// 	this.A = A;
// 	this.start = start;
// }
// 		
// @Override
// public String getMessage()
// {
// 	StringBuilder sb = new StringBuilder()
// 		.append(super.getMessage())
// 		.append(System.getProperty("line.separator"))
// 		.append(start != null ? start.toString() : "LCP is null")
// 		.append(System.getProperty("line.separator"))
// 		.append(A.toString());
// 	return sb.toString();
// }
//   }


// Path: lib-algo/src/lse/math/games/lcp/LexicographicMethod.java
import lse.math.games.lcp.LemkeAlgorithm.RayTerminationException;

package lse.math.games.lcp;


// This class seems specific to the representation of the Tableau?
// See if I can decouple from specifics of Tableau
// See if I can decouple from LCP specifics (read: z0leave)
//
// This class takes an var to enter the basis and determines which
// var should leave.
//
// This needs to be split into two parts, one part belongs in Lemke, the other in Tableau
public class LexicographicMethod
{
    public int[] tested;        //TODO: make private
    public int[] comparisons;   //TODO: make private  
    private int[] leavecand;    /* leavecand [0..numcand-1] = candidates (rows) for leaving var */ 
    private LCP start;

    public LexicographicMethod(int basisSize, LCP start)
    {
	this.start = start;
        leavecand = new int[basisSize];
        InitStatistics(basisSize + 1);
    }

    //region Minimum Leaving Variable
    private boolean z0leave;
    
    /**
     * z0leave
     * ==========================================================
     * @return the state of the z0leave boolean following the 
     * last call to minVar().  Indicates that z0 can leave the
     * basis, but the lex-minratio test is performed fully,
     * so the returned value might not be the index of  z0.
     */
    public boolean z0leave() { return z0leave; }

    /** 
     * minVar
     * ===========================================================
     * @return the leaving variable in  VARS, given by lexmin row, 
     * when  enter  in VARS is entering variable
     * only positive entries of entering column tested
     * boolean  *z0leave  indicates back that  z0  can leave the
     * basis, but the lex-minratio test is performed fully,
     * so the returned value might not be the index of  z0
     */
    public int lexminratio(Tableau A, int enter)
    	throws RayTerminationException
    {
        z0leave = false;                                                
        
        // TODO: I think I can comment for perf... (but a unit test will fail)
        // I could pass in a cobasic index instead
        A.vars().assertNotBasic(enter);
        int col = A.vars().col(enter);
                      
        int numcand = 0;
        for (int i = 0; i < leavecand.length; i++) {                    /* start with  leavecand = { i | A[i][col] > 0 } */
            if (A.isPositive(i, col)) {
                leavecand[numcand++] = i;
            }
        }


        if (numcand == 0) {
