// (C)2007 Attila Kovacs <attila@submm.caltech.edu>

import java.util.*;

class SourceBoxingThread extends Thread {
		public volatile static Vector2D minOffset, maxOffset;
		
		Vector<LabocaScan[]> scans = new Vector<LabocaScan[]>();
		MiniCRUSH crush;
		
		public SourceBoxingThread(MiniCRUSH crush) { this.crush = crush; }
		
		public void addScan(LabocaScan[] scan) { 
			scans.add(scan); 
			for(int k=0; k<scan.length; k++) crush.queue.add(scan[k]);
		}
		
		public void run() {		
			double mindX = Double.POSITIVE_INFINITY, maxdX = Double.NEGATIVE_INFINITY;
			double mindY = Double.POSITIVE_INFINITY, maxdY = Double.NEGATIVE_INFINITY;
			
			for(LabocaScan[] scan : scans) for(int k=0; k<scan.length; k++) {
				
				final LabocaScan subscan = scan[k];
				final int[] channelSelection = subscan.allSkyChannels;
				
				subscan.map = crush.map;
				
				for(int t=0; t<subscan.frames; t++) {
					final LabocaFrame exposure = subscan.frame[t];
					if(exposure != null) if((exposure.flag & LabocaFrame.SKIP_SOURCE) == 0) {

						for(int q=0; q<channelSelection.length; q++) {
							final Vector2D offset = subscan.getMapOffsets(t, channelSelection[q]);

							if(offset.x < mindX) mindX = offset.x;
							else if(offset.x > maxdX) maxdX = offset.x;
							if(offset.y < mindY) mindY = offset.y;
							else if(offset.y > maxdY) maxdY = offset.y;		
						}
					}
				}
				
				updateCorners(mindX, mindY, maxdX, maxdY);
				crush.checkout(subscan);
			}
		}	
		
		public static synchronized void updateCorners(double mindX, double mindY, double maxdX, double maxdY) {
			if(minOffset == null) {
				minOffset = new Vector2D(mindX, mindY);
				maxOffset = new Vector2D(maxdX, maxdY);
			}
			else {
				minOffset.x = Math.min(mindX, minOffset.x);
				minOffset.y = Math.min(mindY, minOffset.y);
				maxOffset.x = Math.max(maxdX, maxOffset.x);
				maxOffset.y = Math.max(maxdY, maxOffset.y);
			}
		}
	}