import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.Comparator;

public class Driver {

	public static void main(String[] args) {
		
		
		/*
		 * Input to Graph is an adjacencyLIst
		 * the  first row in the adjacency list MUST be the minimal element for JDT to work correctly.
		 * Everything else can be arbitrary.
		 * Inpt to labeled skew Graph incldes labels
		 * The label determines which portion of the graph is skewed out as well as the labeling. 
		 * null entries are skewed out. The ordering of the labeling is the same as the row ordering of the 
		 * adjacency list.
		 */
		
//		Integer [][] adjacencyList = {
//				{1,2},
//				{3,4},
//				{4,5},
//				{6},
//				{6,7},
//				{7,8},
//				{9},
//				{9},
//				{},
//				{}
//		};
//		Integer [] labels = {null, null, null, null, 1, null, 2, 3, 1, 4};
		
//		Integer [][] adjacencyList = {
//				{1,2},
//				{3},
//				{3,4},
//				{5},
//				{5},
//				{}
//		};
//		Integer [] labels = {null, null, null, 1, 1, 2};
//		
////		Slant sum of two 2x2 tablueax
//		Integer [][] adjacencyList = {
//				{1,2},
//				{3},
//				{3,4},
//				{},
//				{5,6},
//				{7},
//				{7},
//				{}
//		};
		
		//2x2 Rectangle
//		Integer [][] adjacencyList = {
//				{1,2},
//				{3},
//				{3},
//				{}
//		};
		
		//2x3 Rectangle
//		Integer [][] adjacencyList = {
//				{1,2},
//				{3},
//				{3,4},
//				{5},
//				{5},
//				{}
//		};
		
		//2x4 rectangle
//		Integer [][] adjacencyList = {
//				{1,2},
//				{3},
//				{3,4},
//				{5},
//				{5,6},
//				{7},
//				{7},
//				{}
//		};
		
		//2x5 rectangle
//		Integer [][] adjacencyList = {
//				{1,2},
//				{3},
//				{3,4},
//				{5},
//				{5,6},
//				{7},
//				{7,8},
//				{9},
//				{9},
//				{}
//		};
//		
		
		//2x6 rectangle
//		Integer [][] adjacencyList = {
//				{1,2},
//				{3},
//				{3,4},
//				{5},
//				{5,6},
//				{7},
//				{7,8},
//				{9},
//				{9,10},
//				{11},
//				{11},
//				{}
//		};
		
		//3x3 rectangle
//		Integer[][] adjacencyList = {
//				{1,2},
//				{3,4},
//				{4,5},
//				{6},
//				{6,7},
//				{7},
//				{8},
//				{8},
//				{}
//		};
		
//		Integer [][] adjacencyList = {
//				{1,2},
//				{3},
//				{3,4},
//				{5},
//				{5},
//				{}
//		};
		
//		Slant sum of  2x2 and 3x3  tablueax
//		Integer [][] adjacencyList = {
//				{1,2},
//				{3,4},
//				{3},
//				{},
//				{5,7},
//				{6,8},
//				{9},
//				{8,10},
//				{9,11},
//				{12},
//				{11},
//				{12},
//				{}
//		};
		
//		Slant sum of  3x3 and 3x3  tablueax
//		Integer [][] adjacencyList = {
//				{1,3},
//				{2,4},
//				{5,9},
//				{4,6},
//				{5,7},
//				{8},
//				{7},
//				{8},
//				{},
//				{10,12},
//				{11,13},
//				{14},
//				{13,15},
//				{14,16},
//				{17},
//				{16},
//				{17},
//				{}
//		};
		
		//Bat n = 0?
//		Integer [][] adjacencyList = {
//				{1},
//				{2},
//				{3},
//				{4,6},
//				{5,7},
//				{8},
//				{7},
//				{8,9},
//				{10},
//				{10,12},
//				{11,13},
//				{14},
//				{13,17},
//				{14,18},
//				{15,19},
//				{16,20},
//				{21},
//				{18},
//				{19},
//				{20},
//				{21,22},
//				{23},
//				{23},
//				{24},
//				{25},
//				{26},
//				{}
//		};
		
//		half tail bat n= 1
//		Integer [][] adjacencyList = {
//				{1,3},
//				{2,4},
//				{5},
//				{4},
//				{5,6},
//				{7},
//				{7,9},
//				{8,10},
//				{11},
//				{10,14},
//				{11,15},
//				{12,16},
//				{13,17},
//				{18},
//				{15,24},
//				{16},
//				{17},
//				{18,19},
//				{20},
//				{20},
//				{21},
//				{22},
//				{23},
//				{},
//				{}
//		};
		
//		half tail bat n= 0
		Integer [][] adjacencyList = {
				{1,3},
				{2,4},
				{5},
				{4},
				{5,6},
				{7},
				{7,9},
				{8,10},
				{11},
				{10,14},
				{11,15},
				{12,16},
				{13,17},
				{18},
				{15},
				{16},
				{17},
				{18,19},
				{20},
				{20},
				{21},
				{22},
				{23},
				{}
		};
		
		
		
//		Integer[][] adjacencyList = {
//				{1,2},
//				{3},
//				{3},
//				{4},
//				{},
//		};
//		
//		Integer[][] adjacencyList2 = {
//				{1,2},
//				{3},
//				{3},
//				{},
//		};
		
//		Graph g = Shape.makeShape(3, 3);
//		Integer[] labels = {null, null, null, null, 1, 1, 2, 3, 4};
//		long startTime = System.currentTimeMillis();
		Graph g = new Graph (adjacencyList);
//		g.idealURTs();
		
//		System.out.println(g.tailTest(4));
//		URTsDb db = g.sqlIdealURTs("twoxtwo", 10000);
//		long endTime   = System.currentTimeMillis();
//		long totalTime = endTime - startTime;
//		System.out.println(totalTime);
//		db.allURTs();
//		db.allNonURTs();
		
		
//		LabeledSkewGraph lsg = new LabeledSkewGraph(g, labels);
//		lsg.rectify();
		
//		Ideal ideal = new Ideal(g, new HashSet<Integer>(), new HashSet<Integer>());
//		ideal = ideal.addEmptyNodes(Arrays.asList(0,1,2,3,4));
//		System.out.println(ideal.minimalFilling());
//		
//		for (int i = 0; i < 10; i++){
//			iterator.next();
//		}
//		LabeledSkewGraph lg = iterator.next();
//		lg.display();
//		lg.rectify();
		
		
		
		URTsTuple urtsTup = g.idealURTs();
		urtsTup.countDisplay();
		//urtsTup.display();
//		System.out.println("hi");
		System.out.println(urtsTup.hasAllShapes(g));
		System.out.println(urtsTup.hasMinimalFillings(g));
		
//		ArrayList<Ideal> ideals = g.allIdeals();
//		System.out.println(ideals.size());
//		int i = 0;
//		int j = 0;
//		for (Ideal ideal : ideals){
//			LabeledSkewGraphIterator iterator = new LabeledSkewGraphIterator(ideal);
//			while (true){
//				LabeledSkewGraph lg = iterator.next();
//				if (lg == null) {break;}
//				i += 1;
//			}
//			j += 1;
//			System.out.println(j + " " + i);
//		}
		//Ideal ideal = new Ideal(g, new HashSet<Integer>(), new HashSet<Integer>());
		//ideal = ideal.addEmptyNodes(Arrays.asList(0));
//		ideal.display();
//		LabeledSkewGraphIterator iterator = new LabeledSkewGraphIterator(ideal);
//		int i = 0;
//		while (true){
//			LabeledSkewGraph lg = iterator.next();
//			if (lg == null) {break;}
//			lg.display();
//			i += 1;
//		}
		
		//LabeledSkewGraph sg = new LabeledSkewGraph(g, labels);
		
		//sg.rectify();
		
//		int[] sizes = {10000,100000,1000000};
//		for (int size: sizes){
//			long startTime = System.currentTimeMillis();
//			URTsDb db = new URTsDb("___test___"+size, size);
//			for (int i=0; i < 1000000; i++){
//				db.add("this is a big test", "this is a bigger test") ;
//			}
//			long endTime   = System.currentTimeMillis();
//			long totalTime = endTime - startTime;
//			System.out.println(size + ": " + totalTime);
//		}
		
	}

}
