

    public void drawFrame4D(Graphics2D g,Manager M) {
	double [] d=M.C.CON_P.getExtendedFiber();
   	double A=d[2];
	GeneralPath gp=new GeneralPath();
        float x=(float)(1+A);
        gp.moveTo(0,0);
	gp.lineTo(0,x);
	gp.lineTo(x,x);
	gp.lineTo(x,0);
	gp.closePath();
        gp=M.PE.transform(gp); 
        g.setColor(Color.white);
        g.draw(gp);
	gp.reset();

	double u=d[1];

	float x5=0;
	float x6=0;

	 x5=(float)(d[0]+d[1]-3.5);
	 x6=(float)(d[0]+d[1]+A-2.5);
         gp.moveTo(x5,x);
	 gp.lineTo(x6,0);
	 gp=M.PE.transform(gp); 
         g.draw(gp);
	 gp.reset();

	 x5=(float)(d[0]+d[1]-1.5);
	 x6=(float)(d[0]+d[1]+A-.5);
         gp.moveTo(x5,x);
	 gp.lineTo(x6,0);
	 gp=M.PE.transform(gp); 
         g.draw(gp);
	 gp.reset();

         x5=(float)(d[0]+d[1]+.5);
	 x6=(float)(d[0]+d[1]+A+1.5);
         gp.moveTo(x5,x);
	 gp.lineTo(x6,0);
	 gp=M.PE.transform(gp);
         g.draw(gp);
	 gp.reset();



	 x5=(float)(d[0]-d[1]-3.5);
	 x6=(float)(d[0]-d[1]+A-2.5);
         gp.moveTo(x5,x);
	 gp.lineTo(x6,0);
	 gp=M.PE.transform(gp); 
         g.draw(gp);
	 gp.reset();

	 x5=(float)(d[0]-d[1]-1.5);
	 x6=(float)(d[0]-d[1]+A-.5);
         gp.moveTo(x5,x);
	 gp.lineTo(x6,0);
	 gp=M.PE.transform(gp); 
         g.draw(gp);
	 gp.reset();

	 x5=(float)(d[0]-d[1]+.5);
	 x6=(float)(d[0]-d[1]+A+1.5);
         gp.moveTo(x5,x);
	 gp.lineTo(x6,0);
	 gp=M.PE.transform(gp); 
         g.draw(gp);
	 gp.reset();



	 gp.moveTo(-10,-10);
	 gp.lineTo(0,-10);
	 gp.lineTo(0,10);
	 gp.lineTo(-10,10);
	 gp.closePath();
	 g.setColor(Color.black);
	 gp=M.PE.transform(gp); 
         g.fill(gp);
	 gp.reset();


	 gp.moveTo(10,-10);
	 gp.lineTo(x,-10);
	 gp.lineTo(x,10);
	 gp.lineTo(10,10);
	 gp.closePath();
	 g.setColor(Color.black);
	 gp=M.PE.transform(gp); 
         g.fill(gp);
	 gp.reset();


        gp.moveTo(0,0);
	gp.lineTo(0,x);
	gp.lineTo(x,x);
	gp.lineTo(x,0);
	gp.closePath();
        gp=M.PE.transform(gp); 
        g.setColor(Color.white);
        g.draw(gp);
	gp.reset();




	 g.setColor(Color.white);



	float x1=(float)(1+2*A*u-A);
	if(u<0) x1=(float)(2*A+2*A*u);
         gp.moveTo(x1,0);
	 gp.lineTo(x1,x);
	 gp.closePath();
	 gp=M.PE.transform(gp); 
         g.setColor(Color.white);
         g.draw(gp);
	 gp.reset();

	float x2=(float)(2*A-2*A*u);
	if(u<0) x2=(float)(1-A-2*A*u);
         gp.moveTo(0,x2);
	 gp.lineTo(x,x2);
	 gp.closePath();
	 gp=M.PE.transform(gp); 
         g.draw(gp);
	 gp.reset();

	float x3=(float)(2*A*u);
	if(u<0) x3=(float)(1+A+2*A*u);
         gp.moveTo(x3,0);
	 gp.lineTo(x3,x);
	 gp.closePath();
	 gp=M.PE.transform(gp); 
         g.draw(gp);
	 gp.reset();

	float x4=(float)(1+A-2*A*u);
	if(u<0) x4=(float)(-2*A*u);
	 gp.moveTo(0,x4);
	 gp.lineTo(x,x4);
	 gp.closePath();
	 gp=M.PE.transform(gp); 
         g.setColor(Color.white);
         g.draw(gp);
	 gp.reset();
    }




/*This routine draws the arithmetic graph for orbits not on the
  special lines */


    public ArithmeticGraphLocal doLocalDynamic(int i,int j,double AA) {
        double strip=M.C.CON_G.AGC.AGO.getStripShift();   //how far into the strip
	ArithmeticGraphLocal L=new ArithmeticGraphLocal();
	L.gp=new GeneralPath();
	ArithmeticPoint P1=new ArithmeticPoint();
	P1.m=i;
	P1.n=j;
	ArithmeticPoint P2=new ArithmeticPoint();
	Complex test=toComplex(P1,AA);

	L.x[0]=-2;
	L.x[1]=-2;
	L.x[2]=-2;
	L.x[3]=-2;

	int parity=(i+j+1000000)%2;
	int PARITY=M.C.CON_G.AGC.AGO.parity;  should be 0 or 1
	if(test.x>0) {
	    P1.y=-1+strip;
	    if(parity==PARITY) P1.y=1+strip;
            P2=firstReturnDirected(P1,AA,0);
	    L.gp.moveTo(P2.m,P2.n);
	    L.x[0]=P2.m-P1.m;
	    L.x[1]=P2.n-P1.n;
            P2=firstReturnDirected(P1,AA,1);
	    L.gp.lineTo(P1.m,P1.n);
	    L.gp.lineTo(P2.m,P2.n);
            L.x[2]=P2.m-P1.m;
	    L.x[3]=P2.n-P1.n;
	}
	return(L);
    }



//also for drawing the more general version of the a.g.

    public void orbitPlot() {
	double strip=M.C.CON_G.AGC.AGO.getStripShift();
	/*initialize point*/
	int direction=M.C.CON_G.AGC.getOption();
	ArithmeticPoint P=new ArithmeticPoint(SOURCE);
	int PARITY=0;
	//	int PARITY=M.C.CON_G.AGC.AGO.parity;
	int parity=(P.m+P.n+100000)%2;
	P.y=strip-1.0;
	if(parity==PARITY)	P.y=1.0+strip;

	ArithmeticPoint P1=new ArithmeticPoint(P);
	ArithmeticPoint P2=new ArithmeticPoint(P);

	double LIM=Math.pow(2,M.C.CON_G.AGC.INT[0].val);
	halt=1;
        GeneralPath gp=new GeneralPath();
	int count=0;

       	while((halt==1)&&(count<LIM)) {
	    P2=firstReturnDirected(P1,A,direction);
            gp.moveTo(P1.m,P1.n);
	    gp.lineTo(P2.m,P2.n);
	    P1=new ArithmeticPoint(P2);
	    if(P2.testSame(P2,P)==1) halt=0;
	    sendMessage(count);
	    ++count;
	}

	halt=0;
	M.R.nextPathLast(gp);
	M.R.repaint();
    }




/*this uses the polytope exchange to compute the arithmetic graph*/

    public static ArithmeticGraphLocal doLocalPolytope(int i,int j,double AA) {
	ArithmeticGraphLocal L=new ArithmeticGraphLocal();
	L.gp=new GeneralPath();
	int[][] X1=new int[2][2];
	int[][] X2=new int[2][2];
	X1[0][0]=i;
	X1[0][1]=j;
	int[] mp=TorusMap.finalPlus(AA,i,j);
	int[] mm=TorusMap.finalMinus(AA,i,j);
	L.x[0]=mp[0];
	L.x[1]=mp[1];
	L.x[2]=mm[0];
	L.x[3]=mm[1];
	L.gp.moveTo(i,j);
	L.gp.lineTo(i+mp[0],j+mp[1]);
	L.gp.moveTo(i,j);
	L.gp.lineTo(i+mm[0],j+mm[1]);
	return(L);
    }






/*These routines deal with the partition-dynamics of the
  polytope exchange map from the Master Pictre Theorem.*/


    public int inWindow(int mode,Complex z,Complex lim1,Complex lim0) {
	if(mode==0) return(1);
	if(z.x<Math.min(lim1.x,lim0.x)) return(0);
	if(z.x>Math.max(lim1.x,lim0.x)) return(0);
	if(z.y<Math.min(lim1.y,lim0.y)) return(0);
	if(z.y>Math.max(lim1.y,lim0.y)) return(0);
	return(1);
    }


    public void periodic() {
	M.PE.point=0;
	Complex Z=M.C.CON_P.getFiber();
	double A=Z.y;
        double LIM=Math.pow(2,M.C.CON_S.ITER.val);  //plot density
	LIM=Math.sqrt(LIM);
	int which=M.C.CON_P.getFiberSelect();

	Complex lim0=new Complex(M.PE.WINDOW[0]);
	Complex lim1=new Complex(M.PE.WINDOW[1]);
	int mode=0;

	int depth=(int)(Math.pow(2,M.C.CON_S.DEPTH.val));
	for(int i=0;i<LIM;i=++i) {
	  for(int j=0;j<LIM;++j) {
            double[] d1=new double[4];
	    d1[0]=which;
	    d1[1]=(A+1.0)*i/LIM;
	    d1[2]=(A+1.0)*j/LIM;
	    d1[3]=Z.x;

	    Complex ww=new Complex(d1[1],d1[2]);                   
	    int mod=M.C.CON_S.MOD.val;

	    if(inWindow(mode,ww,lim1,lim0)==1) {
              int test=ExchangeDynamics.getPeriod(depth,A,d1);
	      if(test<depth) {
		for(int q=0;q<mod;++q) {
		    if(test%mod==q) M.PE.addPoint(ww,M.C.CON_P.PEC.COLOR.L[q].C);
		}
	      }
	    }
	  }
	}
	M.PE.repaint();
    }


    public Color assignColor(int test,int depth,int mod) {
	Color COL=Color.black;
	if(test<depth) {
	     for(int qq=0;qq<mod;++qq) {
	         if(test%mod==qq) COL=M.C.CON_P.PEC.COLOR.L[qq].C;
	     }
	}
	return(COL);
    }

    public Color assignColor2(int test,int depth,int mod) {
	Color COL=Color.black;
	if(test<depth) {
	     for(int qq=0;qq<15;++qq) {
	         if((test>=Math.pow(2,qq))&&(test<Math.pow(2,qq+1))) COL=M.C.CON_P.PEC.COLOR.L[qq].C;
	     }
	}
	return(COL);
    }

    */


    /*

    public void periodic2() {
	M.PE.path=0;
	int p=M.C.SES.getNumerator();
	int q=M.C.SES.getDenominator();
  	int r=M.C.CON_P.PEC2.SLICE.val;
        int which=M.C.CON_P.getFiberSelect();	
        int depth=(int)(Math.pow(2,M.C.CON_S.DEPTH.val));
	Color COL;
	GeneralPath gp=new GeneralPath();  
        int mod=M.C.CON_S.MOD.val;

	A=1.0*p/q;
        double[] d1=new double[4];
        d1[0]=which;
	int test=0;
	for(int i=0;i<p+q;++i) {
	    for(int j=0;j<p+q;++j) {

		d1[1]=1.0*i/q+1.0/(6*q);
		d1[2]=1.0*j/q+1.0/(6*q);
	        d1[3]=(2*r+1.0)/(2*q);
                test=ExchangeDynamics.getPeriod(depth,A,d1);
		COL=assignColor(test,depth,mod);
                gp=ExchangeDynamics.special1(q,i,j);
		M.PE.addPath(gp,COL);

		d1[1]=1.0*i/q+3.0/(6*q);
		d1[2]=1.0*j/q+3.0/(6*q);
	        d1[3]=(2*r+1.0)/(2*q);
                test=ExchangeDynamics.getPeriod(depth,A,d1);
		COL=assignColor(test,depth,mod);
                gp=ExchangeDynamics.special2(q,i,j);
		M.PE.addPath(gp,COL);

		d1[1]=1.0*i/q+5.0/(6*q);
		d1[2]=1.0*j/q+5.0/(6*q);
	        d1[3]=(2*r+1.0)/(2*q); 
                test=ExchangeDynamics.getPeriod(depth,A,d1);
                COL=assignColor(test,depth,mod);
                gp=ExchangeDynamics.special3(q,i,j);
		M.PE.addPath(gp,COL);

	    }
	}

	M.PE.repaint();
    }
    */

    /*
    public void fourD() {
	double [] d=M.C.CON_P.getExtendedFiber();
	Complex z=new Complex();
	Color COL=Color.black;
	double A=d[2];
        double LIM=Math.pow(2,M.C.CON_S.ITER.val);  //plot density


	for(int i=0;i<LIM;i=++i) {
	    z.x=4.0*i+2*d[0]+.00000001;
	    z.y=2*d[1];
	    COL=computeColor(A,z,M); 
	    double[] w=TorusMap.phi4D(A,z.x,z.y);
	    Complex ww=new Complex(w[0],w[1]);
	    M.PE.addPoint(ww,COL);
	}


	M.PE.repaint();

    }
    */