	
class SpecViewer112 : object
{
image profile	
number Cube1ID,TargetID,ProfileID,Sel_ID
number depth,FastPix
number List1,ListP,ListW1
number sourceType

image cX,cY, mask2D
image MSAmatrix

image GetMaskAndSpectrum(object self,image MSAmatrix,roi Select)
	{
	number top,left,bottom,right
	Select.ROIGetRectangle(top,left,bottom,right)
	
	mask2D = tert((left<=cX)&&(cX<=right)&&(top<=cY)&&(cY<=bottom),1,0)	
	image mask = MSA112_Convert2DtoColumn(mask2D)

	image Spec	
	number kN
	if((max(mask)>0))
		{
		MSA112_TakeCluster(MSAMatrix,mask,1,0,Spec,kN) //return reddataMatrix (NOT used)
		}
	else spec:= realimage("",4,depth,1)
		
	return Spec
	}
		
image GetSpectrum(object self,image Cube,roi Select,number depth)
	{	
	number top,left,bottom,right
	Select.ROIGetRectangle(top,left,bottom,right)
	
	if(bottom==top) exit(0)
	if(right==left) exit(0)

	image fragm = Cube[left,top,0,right,bottom,depth]
	
	return fragm.MSA112_Render3DtoPixel()/(bottom-top)/(right-left)
	}

void RemoveAll(object self)
	{
	
	//remove listener in live-spectrum
	if(Profile.ImageIsValid())
		{
		ImageDocument SpecDoc = ProfileID.GetImageDocumentByID()
		SpecDoc.ImageDocumentGetWindow().WindowRemoveWindowListener(ListP)
		}
		
	//find target image (where roi is)
	image target := targetID.FindImageByID()
	
	//remove listener in target	display
	imageDisplay imdisp = target.ImageGetImageDisplay(0)
	imdisp.ImageDisplayRemoveEventListener(List1)
	
	//remove ROI in target
	roi Sel = GetRoiFromID(Sel_ID)
	if(imdisp.ImageDisplayDoesROIExist("Selection"+Sel_ID)) imdisp.ImageDisplayDeleteROI(Sel)

	//remove listener in target	window
	ImageDocument doc = target.ImageGetOrCreateImageDocument()
	if(doc.MSA112_CheckImageWindow()) 
		{
		DocumentWindow Win = doc.ImageDocumentGetWindow()
		Win.WindowRemoveWindowListener(ListW1)
		}
		
	//delete temporary images	
	if(sourceType ==1) //source: scatter plot
		{
		deleteimage(cX)
		deleteimage(cY)
		deleteimage(MSAmatrix)
		}
		
	if(sourceType ==3) //source: MSA image
		{
		image Cube1 := Cube1ID.FindImageByID()
		deleteimage(Cube1)
		}	
	}

void UpdateProfiles(object self,roi sel)
	{
	if(sourceType ==1) Profile = self.GetMaskAndSpectrum(MSAmatrix,Sel)	//source:scatterplot
	if(sourceType >=2) Profile = self.GetSpectrum(Cube1ID.FindImageByID(),Sel,depth)
	}
	
void RoiChanged(object self,number e_fl,imageDisplay imdisp,number r_fl,number r_fl2,ROI Sel)
	{
//result("\nchanged "+e_fl+" "+r_fl+" "+r_fl2)
	if(ROIGetID(Sel)==Sel_ID)//if(ROIGetLabel(Sel)=="Y")
		{
		self.UpdateProfiles(sel)
		}
	}

void RoiShifted(object self,number e_fl,imageDisplay imdisp,number r_fl,number r_fl2,ROI Sel)
	{
	number top,left,bottom,right
	Sel.ROIGetRectangle(top,left,bottom,right)
//result("\n"+top+" "+left+" "+bottom+" "+right)	

	number e_fl,r_fl,r_fl2 
	
	if(((bottom-top)*(right-left) <= FastPix)) self.RoiChanged(e_fl,imdisp,r_fl,r_fl2,Sel)
	}
	
void RoiRemoved(object self,number e_fl,imageDisplay imdisp,number r_fl,number r_fl2,ROI Sel)
	{
	if(Sel.roiGetID()==Sel_ID)
		{	
		self.RemoveAll()
		}
	}

void SpectrumRemoved(object self, number e_fl, DocumentWindow Win)
    {
    self.RemoveAll()
	}

void CubeRemoved(object self, number e_fl, DocumentWindow Win)
    {
	self.RemoveAll()
	}

void HideCube(object self, image Cube,DocumentWindow win)
	{
	number x,y
	WindowgetFramePosition(win,x,y)
	documentWindow winCube = Cube.ImageGetOrCreateImageDocument().ImageDocumentGetWindow()
	WindowSetFramePosition(winCube,x,y)
	WindowSendBehind(winCube,win)	
	}

void ManageWeighting(object self, image &MSAmatrix,taggroup MatrixTags)
	{
	if(!shiftdown()) 
		{
		image avSpec = MSA112_GetAverageSpectrum(MatrixTags)
		image AvImage = MSA112_GetAverageImage(MatrixTags)
		MSA112_DeWeighting(MSAmatrix,avSpec,AvImage)		
		}
	}
	
object init(object self)
	{
result("\nSpectrumViewer initialized")

	image target
	string Name
	string Type

	//figure out the type of source
		target:= GetFrontImage()
		targetID = target.ImageGetID()	
		
		if(target.ImageGetNumDimensions()==3)	//any 3D images are regarded as spectrum-image
			{
			sourceType = 2		//source: spectrum-image	
			}
		else
			{	
			TagGroup TargetTags = target.ImageGetTagGroup()
			TargetTags.TagGroupGetTagAsString(MSA112_Label() +":type",type)
//result("\nType "+Type)				
			if(Type == "MSA matrix") sourceType = 3
			if(Type == "MSA scatterPlot") sourceType = 1
			}
			
		if(sourceType==0)	//not recognized as valid target
			{
			OkDIalog("put in front: \nspectrum-image or\nMSAimage or\nscatterplot")
			exit(0)
			}
			
		number width,height, Points
		number origin,disp
		string units
		DocumentWindow Win1
		imageDisplay imDisp1

		//get window
		Win1 = target.ImageGetOrCreateImageDocument().ImageDocumentGetWindow()
		
	if(sourceType ==1)	//source: scatter plot
		{
		//read scatter tags
		TagGroup ScatterTags = target.MSA112_getScatterTags()
		
		//get MSA image
		image MSAimage := MSA112_OpenImageFromGlobalID(ScatterTags,"","MSA Matrix")
			
		//get size
		tagGroup MatrixTags = MSAimage.ImageGetTagGroup()
		number widthMask,heightMask
		MatrixTags.MSA112_GetSISizes(Points,depth,widthMask,heightMask)
		target.getSize(width,height)
		
		//load coordinates and create masks
		cX :=ScatterTags.MSA112_GetImageFromTags("Coordinates-X") 
		cY :=ScatterTags.MSA112_GetImageFromTags("Coordinates-Y") 
		Mask2D := integerimage("",2,0,widthMask,heightMask) 
		Mask2D.setName("current mask")
		Mask2D.showimage()
		
		//set name	
		Name = MSAimage.getName()
			
		//get calibration
		MatrixTags.MSA112_GetCalibration(disp,origin,units,"E")
		
		//get data matrix
		MSAmatrix := MSAimage.MSA112_GetMSAMatrix()
		self.ManageWeighting(MSAmatrix,MatrixTags)
		}
		
	if(sourceType ==2)	//source: spectrum-image
		{
		image Cube1 := target	
		
		//get size
		Cube1.get3DSize(width,height,depth)	
//result("\n"+width+"x"+height+"x"+depth)
		
		//set source ID
		Cube1ID = targetID

		//set name	
		Name = Cube1.getName()

		//get calibration
		Cube1.ImageGetDimensionCalibration(2,origin,disp,units,1)	
		}

	if(sourceType ==3)	//source: MSA image
		{
		tagGroup MatrixTags = target.ImageGetTagGroup()
		
		//get size
		MatrixTags.MSA112_GetSISizes(Points,depth,width,height)
//result("\n"+width+"x"+height+"x"+depth)

		//get matrix
		image MSAmatrix = target.MSA112_GetMSAMatrix()
		self.ManageWeighting(MSAmatrix,MatrixTags)

		//create cube
		image Cube1 = MSA112_Convert2Dto3D(MSAmatrix,width,height)
		Cube1.showimage()
		self.HideCube(Cube1,win1)
		
		//set source ID
		Cube1ID = Cube1.ImageGetID()
	
		//set name
		Name = target.getName()
//result("\nID1 "+Cube1ID +" "+ ImageIsValid(Cube1ID.FindImageByID()) )	
		
		//get calibration
		MatrixTags.MSA112_GetCalibration(disp,origin,units,"E")
		}
	
	//set fastpixel
	FastPix = 2048/depth*MSA112P_FastPixel() // GMS1: 6x6 pixels at 2048 Depth
	if(sourceType ==1) FastPix = 0	//no fast update
	
	//setROI
	roi Sel = NewRoi()
	Sel_ID = Sel.roiGetID()
	Sel.ROISetName("Selection"+Sel_ID)
//result(" ROI ID "+Sel_ID)
	number inileft,iniright,initop,inibottom
	if(sourceType >1) //sources: spectrum-image,MSA image
		{
		inileft = width/2
		iniright = width/2+1
		initop = height/2
		inibottom = height/2+1
		}
	if(sourceType ==1) //source: scatter plot
		{
		inileft = width*3/8
		iniright = width*5/8
		initop = height*3/8
		inibottom = height*5/8
		}
	Sel.ROISetRectangle(initop,inileft,inibottom,iniright)
	Sel.ROISetColor(0,1,0)
	Sel.ROISetLabel("Y")
	
	//attach ROI to the right display
	imDisp1 = target.ImageGetImageDisplay(0)
	imDisp1.ImageDisplayAddROI(Sel)
	
	//set spectrum
	Profile := realImage("Spectrum of "+Name,4,depth,1)
	Profile.ImageSetDimensionCalibration(0,origin,disp,units,1)
	Profile.showimage()
	
	//initial spectrum
	self.UpdateProfiles(sel)

	//attach listeners
	imageDocument SpecDoc = getFrontImageDocument()
	ProfileID = SpecDoc.ImageDocumentGetID()
	DocumentWindow SpecWin = SpecDoc.ImageDocumentGetWindow()
	ListP = SpecWin.WindowAddWindowListener(self,"window_closed:SpectrumRemoved")
	ListW1 = Win1.WindowAddWindowListener(self,"window_closed:CubeRemoved")
	string messageMap = "roi_removed:RoiRemoved;roi_end_track:RoiChanged;roi_changed:RoiShifted"
	List1 = imDisp1.ImageDisplayAddEventListener(self,messageMap)
	
	return self
	}
	
~SpecViewer112(object self) 
	{
	result("\nSpectrumViewer destroyed")
	}
}

void createall()
{
object Viewer = alloc(SpecViewer112).init(); 
}

createall()