import edu.neu.ccs.demeterf.demfgen.classes.*;
import edu.neu.ccs.demeterf.demfgen.DemFGenMain;
import edu.neu.ccs.demeterf.inline.classes.*;
import edu.neu.ccs.demeterf.inline.*;
import edu.neu.ccs.demeterf.lib.List;
import edu.neu.ccs.demeterf.lib.Map;
import edu.neu.ccs.demeterf.lib.ident;
import edu.neu.ccs.demeterf.*;

/** I use this class to test out quick Java stuff in Eclipse */
public class Test extends FC{
    static void p(String s){ System.out.println(s); }
    
    public static class TheFUNC extends FUNC<Integer,Double>{
        public Double map(Integer i){ return 0.0; }
    }
    public static abstract class FUNC<A,B> extends ID{
        public abstract B map(A a);
        public List<B> combine(List<A> l){ return List.<B>create(); }
        public List<B> combine(List<A> l, A f, List<B> r){ return r.push(map(f)); }
    }
    
    public static void main6(String[] s) throws Exception{
        Inline.main(new String[]{"edu/neu/ccs/demeterf/lib/lib.java.cd","Test$TheFUNC","List(Integer)","--justtype","--strict"});
    }
    static String pad(String s, int n){
        if(n == s.length())return s;
        return " "+pad(s,n-1);
    }
    public static void main(String[] s) throws Exception{
        
        /*TypeUse u = TypeUse.makeType("Test(Foo(Bar))");
        System.out.println(u.toXML());
        */
        
        System.out.println("Test<A(F)>".replaceAll("[<(,>)]", "\\$"));
        
        if(true)return;
        List<CDFile> CDs = DemFGenMain.resolveCDFile("test.cd");
        SubTyping subs = new SubTyping(CDs);
        
        /*p("CD: \n"+CDs.toString(new List.Stringer<DemFGenMain>(){
            public String toString(DemFGenMain f, List<DemFGenMain> r){
                return f.print();
            }
        }));*/
        
        java.text.DecimalFormat form = new java.text.DecimalFormat("0.00");
        
        FunctionClass fs = FunctionClass.fromClass(Test.class,"combine");
        p("Func:\n"+fs+"\nSubs:\n"+subs);
        //p("Part: \n"+partition(fs.meths, 0, 1, subs).toString("\n", ""));
        p("Dec: \n"+Decision.decide("",List.<String>create(),fs.getMeths(), 0, 0, subs, List.<String>create("_h_","op","lft","rt"),1,"","",
                new Decision.Access()));
        
    }
    
    public static void main7(String[] s) throws Exception{
        //FunctionClass fc = FunctionClass.fromClass(Test.class,"update");
        //System.out.println("Methods:\n"+fc);
        List<CDFile> cds = DemFGenMain.resolveCDFile("test.cd");
        
        System.out.println("FIELDS: "+new Traversal(new TU<List<String>>(){
            List<String> mt = List.create();
            public List<String> combine(){ return mt; }
            public List<String> fold(List<String> a, List<String> b){ return a.append(b); }
            
            public List<String> combine(ClassDef c, DoGen d, final ident id, TypeDefParams p, PESubtypeList sts, List<String> fs){
                return fs.map(new List.Map<String, String>(){
                    public String map(String s){ return id+s; }
                });    
            }
            List<String> combine(Field f){ return mt.push("$"+f.getName()); }
        }, Control.bypass(ClassDef.class).removeBypassing(ClassDef.class,"fields")).traverse(cds));
    }
    
    int update(Test t, Fields.any f, int i){ return i; }
    //int update(ID t, tester f, int i){ return i; }
    
    public static void main3(String[] s){
        int i = 1000, min = 1000, diff = 1000;
        while(diff > 0){
            System.out.println("Stack... == "+i);
            try{
                Integer is[] = new Integer[i];
                List<Integer> l = List.create(is);
                min = i;
                i += diff;
            }catch(Error e){
                System.out.println("NEW!! Stack... == "+i);
                diff /= 2;
                i = min + diff;
            }
        }
        System.out.println("Final == "+i);
    }
    public static void main2(String[] s) throws Exception{
        Map<Integer, String> m = Map.create();
        m = m.put(1, "one").put(2, "two");
        
        System.out.println(m.toTreeString());
        System.out.println(m.toString());
        
        System.out.println("OUT:"+Integer.MAX_VALUE);
        
        int b[] = new int[]{0xCA,0xFE,0xBA,0xBE};
        long l = (b[0]<<24) | (b[1]<<16) | (b[2]<<8) | b[3]; 
        System.out.println("OUT:"+Long.toHexString(l));
        System.out.println("OUT:"+Integer.toHexString((int)l));
        System.out.println("test".substring("test".lastIndexOf('/')+1));
        System.out.println("/test/tester".substring("/test/tester".lastIndexOf('/')+1));
    }
    
    //L combine(L l){ return l; }
    //L combine(O o, T l, T r){ return l; }
    //L combine(O o, L l, L r){ return r; }
    E combine(B b, S p, N l, N.Z r){ return l;}
    E combine(B b, S p, E l, N.Z r){ return l;}
    E combine(B b, S p, N l, N r){ return l; }
    E combine(B b, O p, E l, E r){ return l; }
    
    static class E{ }
    static class B extends E{ }
    static class I extends E{ }
    static class N extends E{ 
        static class Z extends N{}
    }
    static class V extends E{ }
    static class D extends E{ }
    static class O {}
    static class S extends O{}
}