
import ltk.*;
import ltk.Button;
import java.awt.*;
import java.awt.image.*; 
import java.awt.Color; 
import java.awt.Event;
import java.io.*;  
import java.util.Vector;   

public class Tracker extends LTKApplet 
       implements CallBackable, Runnable{
//parameters 
static double 
	NORTH,
	LEFTAZIMUTHSTART, 
	LEFTAZIMUTHSTOP,
	LEFTCENTERELEVATION,
	RIGHTAZIMUTHSTART,
	RIGHTAZIMUTHSTOP,
	RIGHTCENTERELEVATION,
	STEP,
	CAMERA1REF,
	CAMERA2REF;

static String DIODE;  
                                 
lPicture pictLeft,pictRight;  
java.awt.Image myLeftImage, myRightImage; 

public void run(){             
java.awt.MediaTracker myTracker;     
Layout vlayout;            
String LeftString, RightString;  
myTracker = new java.awt.MediaTracker(this); 
canvas.freeze();
if (running_as_applet) {                 
myLeftImage =getImage(getDocumentBase(),
	LeftString = getParameter( "LeftImage"));   
myRightImage=getImage(getDocumentBase(),
	RightString=getParameter("RightImage"));
//System.out.println( "LeftString <"+LeftString+">");
//System.out.println("RightString <"+RightString+">");
	}
else
	{
	myLeftImage =  getToolkit().getImage("21H034.gif");
	myRightImage = getToolkit().getImage("22H033.gif");
	}
if (myLeftImage == null){
	System.out.println("Null left Image");
	}
if (myRightImage == null){
	System.out.println("Null right Image");
	}
if ((myLeftImage == null)||(myRightImage == null)){
	stop();
	}
	
myTracker.addImage(myLeftImage,0);
myTracker.addImage(myRightImage,1);
myTracker.checkAll(true); // starts the load process
String northString = new String();
northString = getParameter("NORTH");
if ( northString == null || northString.length()==0){ NORTH = 29.13;}
else
NORTH = Double.valueOf(northString).doubleValue();
// System.out.println("north is "+north);
  String sparam = new String();
  sparam = getParameter( "LEFTAZIMUTHSTART");
  Double DParameter;
  DParameter = Double.valueOf(getParameter ("LEFTAZIMUTHSTART"));
 LEFTAZIMUTHSTART= 
 	Double.valueOf(getParameter ("LEFTAZIMUTHSTART")).doubleValue();   
 LEFTAZIMUTHSTOP= 
 	Double.valueOf(getParameter ("LEFTAZIMUTHSTOP")).doubleValue();      
 LEFTCENTERELEVATION= 
 	Double.valueOf(getParameter ("LEFTCENTERELEVATION")).doubleValue();      
 RIGHTAZIMUTHSTART= 
 	Double.valueOf(getParameter ("RIGHTAZIMUTHSTART")).doubleValue();      
 RIGHTAZIMUTHSTOP= 
 	Double.valueOf(getParameter ("RIGHTAZIMUTHSTOP")).doubleValue();      
 RIGHTCENTERELEVATION= 
 	Double.valueOf(getParameter ("RIGHTCENTERELEVATION")).doubleValue();      
 STEP= Double.valueOf(getParameter ("STEP")).doubleValue();      
 DIODE= getParameter ("DIODE");   
 CAMERA1REF = Double.valueOf(getParameter("CAMERA1REF")).doubleValue();
 CAMERA2REF = Double.valueOf(getParameter("CAMERA2REF")).doubleValue();	 CAMERA1REF = Double.valueOf(getParameter("CAMERA1REF")).doubleValue();

 System.out.println ("NORTH = "+NORTH); 

try{
	while (!myTracker.checkAll()){
		Thread.sleep(1000);
		}
	}
catch(Exception e){
	e.printStackTrace();
	System.exit(1);
	}
		
	
if (myTracker.isErrorAny()){
	System.out.println("At lease one image was not successfully loaded.");
	Object[] list = myTracker.getErrorsAny();
	for (int i = 0; i<list.length; i++){
		System.out.println(list[i]);
		}
	}
boolean abort = false;
for (int i = 0; i < 2; i++){
	int s = myTracker.statusID(i,false);
	if ((s & MediaTracker.COMPLETE)==0){
	System.out.print(((i==0)?"Left":"Right")+"Image :");
	if ((s & MediaTracker.ABORTED) != 0){
		abort = true;
		System.out.print("ABORTED ");
		}
	if ((s & MediaTracker.COMPLETE) != 0)
		System.out.print("COMPLETE ");
	if ((s & MediaTracker.ERRORED) != 0){
		abort = true;
		System.out.print("ERRORED ");
		}
	if ((s & MediaTracker.LOADING) != 0){
		abort = true;
		System.out.print("LOADING ");
		}
	System.out.println();
		}
	}
if (abort){
		System.out.println("Bye");
		showStatus("Can't load Image");
		System.exit(2);
		}
showStatus("Have Both images, matching them");
int leftW = myLeftImage.getWidth(this);
int leftH = myLeftImage.getHeight(this);
int rightW = myRightImage.getWidth(this);
int rightH = myRightImage.getHeight(this);
if (leftW == rightW && leftH == rightH){
// images match in size 
int[] leftPixels = new int[leftW*leftH];
int[] rightPixels = new int[rightW*rightH];
try{
	PixelGrabber Lpg = new PixelGrabber(myLeftImage,0,0,
		leftW, leftH, leftPixels, 0, leftW);
	Lpg.grabPixels();
	// check for errors.
	if ((Lpg.status() & ImageObserver.ABORT) != 0){
		System.err.println("Error while fetching Left image");
		System.exit(1);
		}
	}
catch (Exception e){
	e.printStackTrace();
	System.exit(1);
	}
try{
	PixelGrabber Rpg = new PixelGrabber(myRightImage,0,0,
		rightW, rightH, rightPixels, 0, rightW);
	Rpg.grabPixels();
	// check for errors.
	if ((Rpg.status() & ImageObserver.ABORT) != 0){
		System.err.println("Error while fetching right image");
		System.exit(1);
		}
	}
catch (Exception e){
	e.printStackTrace();
	System.exit(1);
	}
	
// compute averages 
long leftRSum = 0, leftGSum=0, leftBSum=0;
long rightRSum = 0, rightGSum=0, rightBSum=0;
long npixels = leftW*leftH;
ColorModel cm = ColorModel.getRGBdefault();
for (int i = 0; i < npixels ; i++){
	int c = leftPixels[i];
	leftRSum += cm.getRed(c);
	leftGSum += cm.getGreen(c);
	leftBSum += cm.getBlue(c);
	c = rightPixels[i];
	rightRSum+= cm.getRed(c);
	rightGSum+= cm.getGreen(c);
	rightBSum+= cm.getBlue(c);
	}
double leftAverage = ((double) leftRSum +(double) leftGSum+(double)leftBSum)
	/(double)npixels/3.0;
double rightAverage = ((double) rightRSum+(double) rightGSum+(double)rightBSum)
	/ (double)npixels/3.0;
if (leftAverage < rightAverage){
	// scale left pixels
	double ratio = rightAverage/leftAverage;
	// System.out.println("Blue(-2)= "+cm.getBlue(-2));
	
	for (int i = 0; i< npixels; i++){
		int c = leftPixels[i];
		leftPixels[i]=((0xfff<<8|
		(int)(cm.getRed(c)*ratio))<<8|
		(int)(cm.getGreen(c)*ratio))<<8|
		(int)(cm.getBlue(c)*ratio);
		if (i<10){
			// System.out.println("pixel "+i+" was "+c+" now "+leftPixels[i]);
			}
		}
	myLeftImage = getToolkit().createImage(
		new MemoryImageSource(leftW,leftH,
		cm, leftPixels, 0, leftW));
	myTracker.addImage(myLeftImage,3);
	}
else
if (rightAverage < leftAverage){
	// scale right pixels  		
	double ratio = rightAverage/leftAverage;
	

	for (int i = 0; i< npixels; i++){
		  	int c = rightPixels[i];
		rightPixels[i]=((0xfff<<8|
		(int)(cm.getRed(c)*ratio))<<8|
		(int)(cm.getGreen(c)*ratio))<<8|
		(int)(cm.getBlue(c)*ratio);

		}
	myRightImage = getToolkit().createImage(
		new MemoryImageSource(rightW, rightH,
		ColorModel.getRGBdefault(), rightPixels, 0, rightW));
	myTracker.addImage(myRightImage,4);
	}
showStatus("waiting for image rebuild");
try{
	myTracker.waitForAll();
	}
catch (Exception e){
	e.printStackTrace();
	}
showStatus("rebuild complete");
canvas.repairArea(canvas.anywhere.x, canvas.anywhere.y,
	canvas.anywhere.w,canvas.anywhere.h);
canvas.unFreeze();
}
	
	
SetUpNotebook();
}
Thread thread;
public void init(){                  
super.init();  
// System.out.println ("Init");
thread = new Thread(this,"Image Wait & Notebook Setup ");
thread.start();
// System.out.println ("thread started");
start();
canvas.freeze();              
}
//     S E T    U P   N O T E B O O K

void SetUpNotebook(){
CTP = new ClipTableProducer();  
notebook = new Notebook(canvas);    
Layout h1, h3, h4;
ltk.Button b1, b2, b3;

b1=  		new ltk.Button(canvas,this,_add,"Add Clips to Clip List");
b2=  		new ltk.Button(canvas,this,_next,"Next Pair of Clips");
b3=  		new ltk.Button(canvas,this,_previous,"Previous pair of Clips"); 

  	h1=	new HorizontalLayout(
		b1, b2, b3,
  		l1 = new ltk.Label(canvas, "Clip List is Empty")
  		);
		h3= new HorizontalLayout(                                                        
    	
    	Constraint.setFixedSize(pictLeft = new lPicture(
		canvas, myLeftImage, 0,0,
		myLeftImage.getWidth(this),myLeftImage.getHeight(this),
		lPicture.LEFT, CTP, currentClipTableEntry)
		), 
    
    	Constraint.setFixedSize(pictRight = new lPicture(
		canvas,myRightImage,0,0, 	
		myRightImage.getWidth(this),myRightImage.getHeight(this)
,
		lPicture.RIGHT, CTP, currentClipTableEntry)
		)
); 	  
notebook.addClient("Select Clips",    
	layout = new VerticalLayout( 
		new ltk.Label(canvas,"Drag mouse with left button down to move or resize clip area"),  
		new ltk.Label(canvas,"If no pictures appear click try clicking in the boxes below "),
	h1,h3)	
	);

/* */
notebook.addClient ("Select Points",
	new VerticalLayout(
		new ltk.Label(canvas, "Select points from each clip here."), 
		new ltk.Label(canvas, "Sometimes the clips overlap. "+
		"If this occurs, go to another tab and return."), 
		
		Constraint.setFixedSize(
			localMap=new LocalMap(canvas,0,0,300,300))   , 	
	
	// line below pulled from full set of buttons
	
	new ltk.Button(canvas,this,_record,"Record Point"),
 
		h4 = new HorizontalLayout(
// Clip layout
			Layout.space(canvas),	
			clipLeft = new Clip(canvas, myLeftImage, 
    				pictLeft,0,0,                                            
 				pictLeft.getClipRect().width , 
				pictLeft.getClipRect().height,LEFT),
			clipRight = new Clip(canvas,myRightImage,
    				pictRight,
    				0,0,                                                        
     				pictRight.getClipRect().width,
				pictRight.getClipRect().height,RIGHT) ,
			Layout.space(canvas)	  
        		),                                                     
		new ltk.Label(canvas, "Go to Map Near Lander to see the plot."),  
		new ltk.Label(canvas, "Go back to select clips to change clips.")  
                  
		)
	); 
/* */    
LocationMap locationMap;
  
notebook.addClient ("Map near lander",
	new VerticalLayout(
		new ltk.Label(canvas, "Viking Scientific Coordiante System"),  
	    	
	  	Constraint.setFixedSize(        
	//	new ltk.Box(canvas,0,0,550,550)
	  		locationMap =new LocationMap(canvas,
	  			pictLeft,pictRight,clipLeft,clipRight, lX, lY)
			)
 
		)
	);
locationMap.setNorth(NORTH);
 locationMap.setCamera1Ref(CAMERA1REF);
 locationMap.setCamera2Ref(CAMERA2REF);
 locationMap.setLeftAzimuthStart(LEFTAZIMUTHSTART); 
 locationMap.setLeftAzimuthStop(LEFTAZIMUTHSTOP);
 locationMap.setLeftCenterElevation(LEFTCENTERELEVATION);
 locationMap.setRightAzimuthStart(RIGHTAZIMUTHSTART);
 locationMap.setRightAzimuthStop(RIGHTAZIMUTHSTOP);
 locationMap.setRightCenterElevation(RIGHTCENTERELEVATION);
 locationMap.setStep(STEP);

  PTP= new PointTableProducer();

notebook.addClient ("Table of points",
	new VerticalLayout(
		new ltk.Label(canvas, "Point Information"),
		pointTable = new ltk.Table(canvas,PTP,
			100,9)
		)
  // end Vertical Layout
	);
h4.setConstraint(Constraint.FixedHeight);
h4.area.h=300;	                                           
h3.setConstraint(Constraint.FixedHeight);  
h3.area.h=512+40;
/* */
layout.rearrange();                              
notebook.selectPage(0);
focus_handler = new FocusHandler();  


canvas.unFreeze();                
} 

public void start(){}

public void stop(){}  

public static void main (String args[]){
	(new Tracker()).runAppletAsApplication("Tracker test");
	} 
	                    
public boolean add(){
	java.awt.Rectangle lRect = pictLeft.getClipRect();
	java.awt.Rectangle rRect = pictRight.getClipRect();
	 boolean first = true;
	 if (first){
		 clipPair = new ClipPair[ArrayMax+1];
		 }
	clipPair[nextClipPair]=new ClipPair(myLeftImage, myRightImage,lRect,rRect);
	if (nextClipPair < ArrayMax) nextClipPair++;
	CTP.addClips(lRect,rRect);
	int n = CTP.howManyPairs();
	
	l1.setLabel(""+((n==0)?"Table is empty":((n==1)?"1 entry in Clip List":
		Integer.toString(n)+" entries in Clip List")));
	 // System.out.println("there are "+n+" entries in table");
	currentClipTableEntry = n-1;
	// System.out.println("currentClipTableEntry = "+currentClipTableEntry);
	pictLeft.setCurrentClip(currentClipTableEntry);
	// System.out.println("pictLeft set");
	pictRight.setCurrentClip(currentClipTableEntry);
	// System.out.println("pictRight set");
	// clipTable.initializeImage();
	// System.out.println("clipTable.initializeImage complete ");
	return true;
	}

public boolean next(){

	int n = CTP.howManyPairs();

	if (++currentClipTableEntry>=n)currentClipTableEntry = n-1;
	// System.out.println("currentClipTableEntry is "+currentClipTableEntry);
	pictLeft.setCurrentClip(currentClipTableEntry);
	pictRight.setCurrentClip(currentClipTableEntry);

	

	return true;

}


public boolean previous(){

	int n = CTP.howManyPairs();

	if (n==0) {

		currentClipTableEntry= -1;

		}

	else

		{

	if(currentClipTableEntry--<0)currentClipTableEntry=0;

		}
	// System.out.println("currentClipTableEntry ="+currentClipTableEntry);
	pictLeft.setCurrentClip(currentClipTableEntry);
	pictRight.setCurrentClip(currentClipTableEntry);

	return true;

	}

public boolean toggle(){
	if(mylUnits == DEGREES)
		{
		mylUnits = PIXELS;
		lUnits.setLabel("Pixels");
		}
	else
		{
		mylUnits = DEGREES;
		lUnits.setLabel("Degrees");
		}
	CTP.setUnits(mylUnits==DEGREES);
	clipTable.initializeImage();
	return true;
	}

public boolean record(){
java.awt.Point left = clipLeft.getClipPoint();
java.awt.Point right = clipRight.getClipPoint();
// System.out.println("Recording current point");
java.awt.Rectangle leftRect = pictLeft.getClipRect();
java.awt.Rectangle rightRect = pictRight.getClipRect();
double leftBase = LocationMap.getLeftBase();
double rightBase = LocationMap.getRightBase();
double leftRefElev=LocationMap.getLeftRefElev();
double rightRefElev=LocationMap.getRightRefElev();
double XX = LocationMap.getXX(left.x+leftRect.x,
	leftBase,
	right.x+rightRect.x,
	rightBase);
double YY = LocationMap.getYY(left.x+leftRect.x,
	leftBase,
	right.x+rightRect.x,
	rightBase);

double ZZ = LocationMap.getZZ(left.x+leftRect.x, 
			   leftBase,
			   rightRect.x+right.x,
			   rightBase,
		leftRect.y+left.y,
			leftRefElev,
		rightRect.y+right.y,
			rightRefElev);  		
int clip = 	lPicture.getCurrentClip();
currentPoint++;


PointTableProducer.addPoint(clip,currentPoint,
left.x + leftRect.x, left.y + leftRect.y,
right.x + rightRect.x, right.y + rightRect.y,
XX,YY,ZZ);

pointTable.initializeImage();
localMap.update();
return true;
}

public boolean delpt(){
		
	int clip = 	lPicture.getCurrentClip();
	PointTableProducer.deletePoint(clip,currentPoint);
	currentPoint--;
	return true;
	}
public boolean nxtpt(){		
	int clip = 	lPicture.getCurrentClip();
	int index = PointTableProducer.findIndexOf(clip,currentPoint);
	if (index > -1) currentPoint = ++index;
	
	return true;
	}
public boolean prvpt(){		
	int clip = 	lPicture.getCurrentClip();
	int index = PointTableProducer.findIndexOf(clip,currentPoint);
	if (index > 0) currentPoint = --index;
	return true;
	}

public boolean hidept(){
	return true;
	}
public String toString(){
	return "Tracker";
	}

public boolean activateCallback(int method_nr){
	switch (method_nr){
case _cancel:
case _quit:
case _leftImage:
case _rightImage:  break;
case _add:return add();
case _next: return next();
case _previous: return previous();
case _exit:
case _toggle: return toggle();
case _record: return record();
case _delpt: return delpt();
case _nxtpt: return nxtpt();
case _prvpt: return prvpt();
case _hidept: return hidept();
		}
	return false;
	}
static  public ClipPair getClipPair(int n){
	 if (n < 0){
		  System.out.println("ClipPair ("+n+") should be positive");
		 return null;
		 }
	 if (n >= nextClipPair){
		 System.out.println("ClipPair ("+n+") must be less than "+nextClipPair);
		 }
	 return clipPair[n];
	 }
 static public int getClipPairLimit(){
	 return nextClipPair - 1;
	 }

static int currentPoint;   
//static int currentRow;              
ltk.Table clipTable;
ltk.Table pointTable;
ltk.Label l1;
static final int _cancel = 1;
static final int _quit = 2;    
static final int _leftImage = 3;
static final int _rightImage = 4; 
static final int _add = 5;
static final int _exit = 6;
static final int _next = 7;
static final int _previous = 8;
static final int _delpt = 9;
static final int _nxtpt = 10;
static final int _prvpt = 11;
static final int _hidept = 12;
static final int _toggle = 13;
static final int _record = 14;
static final int DEGREES = 1;
static final int PIXELS = 2;
static final int LEFT = 0;
static final int RIGHT = 1;

private int mylUnits = DEGREES;
private ltk.Label lUnits;
private int currentClipTableEntry = -1;
private java.awt.MediaTracker myTracker;
private FocusHandler focus_handler;
ltk.Button cancel_button;  
Notebook notebook;
Layout layout;  
Clip clipLeft, clipRight;    
ltk.Label lX, lY;   
static final int ArrayMax = 20;
static int nextClipPair = 0;
static ClipPair[] clipPair;  
ClipTableProducer CTP;  
PointTableProducer PTP;
LocalMap localMap;       
}// end Tracker      
	
	



 
 
 
