COMPILE FUNCTION Comm_Prod_Spec_SI(Instruction, Parm1,Parm2)

/*
	Commuter module for PROD_SPEC_SI (Product Specification SI) window
	
	01/16/2009 - John C. Henry, J.C. Henry & Co., Inc.
*/

DECLARE SUBROUTINE Set_Property, End_Dialog, Send_Event, Set_Status
DECLARE SUBROUTINE ErrMsg, Send_Message, Set_Property, Send_Event,  obj_AppWindow
DECLARE FUNCTION Get_Property, Get_Status, Dialog_Box, Utility, Popup, Collect.Ixvals
DECLARE FUNCTION Send_Message, obj_PR_Spec, Msg, Security_Check, Start_Window

$INSERT MSG_EQUATES
$INSERT APPCOLORS
$INSERT LSL_USERS_EQU
$INSERT PROD_SPEC_EQU
$INSERT QUOTE_SPEC_EQU
$INSERT RECIPE_EQU
$INSERT RECIPE_LAYER_INFO_EQU	;* Another *($&@^! rathole!
$INSERT POPUP_EQUATES

EQU CRLF$	TO \0D0A\

EQU COL$LS_ID			TO 1
EQU COL$REC_NO			TO 2
EQU COL$REC_DESC		TO 3
EQU COL$THK_MIN			TO 4
EQU COL$THK_MAX			TO 5
EQU COL$THK_UNITS		TO 6
EQU COL$RES_MIN			TO 7
EQU COL$RES_MAX			TO 8
EQU COL$RES_UNITS		TO 9
EQU COL$CON_MIN			TO 10
EQU COL$CON_MAX			TO 11
EQU COL$CON_UNITS		TO 12
EQU COL$CRES_MIN		TO 13
EQU COL$CRES_MAX		TO 14
EQU COL$CRES_UNITS		TO 15
EQU COL$CRES_PHASE_MIN	TO 16

EQU COL$DOPANT			TO 2
EQU COL$THK_MEASURE		TO 3
EQU COL$RES_MEASURE		TO 4
EQU COL$CON_MEASURE		TO 5
EQU COL$CRES_MEASURE	TO 6

ErrTitle = 'Error in Comm_Prod_Spec_SI'
ErrorMsg = ''

Result = ''

BEGIN CASE
	CASE Instruction = 'Create'						; GOSUB Create
	CASE Instruction = 'LSATableDC'					; GOSUB LSATableDC
	CASE Instruction = 'LSTableDC'					; GOSUB LSTableDC
	CASE Instruction = 'LSTableDel'					; GOSUB LSTableDel
	CASE Instruction = 'LSATableDel'				; GOSUB LSATableDel
	CASE Instruction = 'Save'						; GOSUB Save
	CASE Instruction = 'LSAPC'						; GOSUB LSAPC
	CASE Instruction = 'LSPC'						; GOSUB LSPC
	
	CASE 1
		ErrorMsg = 'Unknown Instruction passed to routine.'
		ErrMsg(ErrorMsg)
END CASE

RETURN Result


* * * * * *
Create:
* * * * * *

SaveCheckControls = ''

obj_AppWindow('Create')

Set_Property(@WINDOW:'.LS_TABLE','VISIBLE',1)
Set_Property(@WINDOW:'.LSA_TABLE','VISIBLE',1)

ColStyle = Send_Message(@WINDOW:'.LS_TABLE', 'COLSTYLE', COL$REC_NO) 
ColStyle = bitor(ColStyle, 262144)
ColStyle = Send_Message(@WINDOW:'.LS_TABLE', 'COLSTYLE', COL$REC_NO, ColStyle)

ColStyle = Send_Message(@WINDOW:'.LS_TABLE', 'COLSTYLE', COL$THK_UNITS) 
ColStyle = bitor(ColStyle, 262144)
ColStyle = Send_Message(@WINDOW:'.LS_TABLE', 'COLSTYLE', COL$THK_UNITS, ColStyle)

ColStyle = Send_Message(@WINDOW:'.LS_TABLE', 'COLSTYLE', COL$RES_UNITS) 
ColStyle = bitor(ColStyle, 262144)
ColStyle = Send_Message(@WINDOW:'.LS_TABLE', 'COLSTYLE', COL$RES_UNITS, ColStyle)

ColStyle = Send_Message(@WINDOW:'.LS_TABLE', 'COLSTYLE', COL$CON_UNITS) 
ColStyle = bitor(ColStyle, 262144)
ColStyle = Send_Message(@WINDOW:'.LS_TABLE', 'COLSTYLE', COL$CON_UNITS, ColStyle)

ColStyle = Send_Message(@WINDOW:'.LS_TABLE', 'COLSTYLE', COL$CRES_UNITS) 
ColStyle = bitor(ColStyle, 262144)
ColStyle = Send_Message(@WINDOW:'.LS_TABLE', 'COLSTYLE', COL$CRES_UNITS, ColStyle)

Set_Property(@WINDOW:'.LS_TABLE','HEADERHEIGHT',30)

HeaderText = Get_Property(@WINDOW:'.LS_TABLE','LABEL')

HeaderText<COL$REC_NO> = HeaderText<COL$REC_NO>:CHAR(13):'<dc>'
HeaderText<COL$THK_UNITS> = HeaderText<COL$THK_UNITS>:CHAR(13):'<dc>'
HeaderText<COL$RES_UNITS> = HeaderText<COL$RES_UNITS>:CHAR(13):'<dc>'
HeaderText<COL$CON_UNITS> = HeaderText<COL$CON_UNITS>:CHAR(13):'<dc>'
HeaderText<COL$CRES_UNITS> = HeaderText<COL$CRES_UNITS>:CHAR(13):'<dc>'

Set_Property(@WINDOW:'.LS_TABLE','LABEL',HeaderText)
SubstrateInfo	= Parm1[1,CHAR(244)]
EpiInfo			= Parm1[COL2()+1,CHAR(244)]
AddlInfo		= Parm1[COL2()+1,CHAR(244)]
NDInfo			= Parm1[COL2()+1,CHAR(244)]
PPInfo			= Parm1[COL2()+1,CHAR(244)]

CONVERT @SVM TO '' IN EpiInfo

LSCnt = COUNT(EpiInfo,Char(248)) + (EpiInfo NE '')

LSList = ''
LSAList	= ''

FOR I = 1 TO LSCnt

	BEGIN CASE
		CASE I = 1
			Layer = 'L1'
		
		CASE I = 2 
			IF LSCnt = 3 THEN
				Layer = 'L2'
			END ELSE
				Layer = '2'
			END
			
		CASE I = 3 ; Layer = '2'
		CASE 1 ; Layer = I-1
	END CASE
	
	EpiLayer = FIELD(EpiInfo,CHAR(248),I)
	
	LSList<I,COL$LS_ID>			    = Layer
	LSList<I,COL$REC_NO	>		    = EpiLayer<1,QSEpiRecipe$>
	LSList<I,COL$REC_DESC>		    = EpiLayer<1,QSEpiRecipeName$>
	LSList<I,COL$THK_MIN>		    = OCONV(EpiLayer<1,QSEpiMinThick$>,'MD3')
	LSList<I,COL$THK_MAX>		    = OCONV(EpiLayer<1,QSEpiMaxThick$>,'MD3')
	LSList<I,COL$THK_UNITS>		    = EpiLayer<1,QSEpiThickUnits$>
	LSList<I,COL$RES_MIN>		    = OCONV(EpiLayer<1,QSEpiResMinThick$>,'MD3')
	LSList<I,COL$RES_MAX>		    = OCONV(EpiLayer<1,QSEpiResMaxThick$>,'MD3')
	LSList<I,COL$RES_UNITS>		    = EpiLayer<1,QSEpiResUnits$>
	LSList<I,COL$CON_MIN>		    = OCONV(EpiLayer<1,QSEpiConcMinThick$>,'MS21')
	LSList<I,COL$CON_MAX>		    = OCONV(EpiLayer<1,QSEpiConcMaxThick$>,'MS21')
	LSList<I,COL$CON_UNITS>		    = EpiLayer<1,QSEpiConcUnits$>
	LSList<I,COL$CRES_MIN>		    = OCONV(EpiLayer<1,QSEpiCresMin$>,'MD3')
	LSList<I,COL$CRES_MAX>		    = OCONV(EpiLayer<1,QSEpiCresMax$>,'MD3')
	LSList<I,COL$CRES_UNITS>	    = EpiLayer<1,QSEpiCresUnits$>
	LSList<I,COL$CRES_PHASE_MIN>	= EpiLayer<1,QSEpiCresPhaseMin$>
	
	LSAList<I,COL$LS_ID>		    = Layer
	LSAList<I,COL$DOPANT>		    = EpiLayer<1,QSEpiDopant$>
	LSAList<I,COL$THK_MEASURE>	    = EpiLayer<1,QSEpiThickMeasure$>
	LSAList<I,COL$RES_MEASURE>	    = EpiLayer<1,QSEpiResMeasure$>
	LSAList<I,COL$CON_MEASURE>	    = EpiLayer<1,QSEpiConcMeasure$>
	LSAList<I,COL$CRES_MEASURE>	    = EpiLayer<1,QSEpiCresMeasure$>

NEXT I

IF LSCnt = 0 THEN
	LSList = STR(@VM,16)
	LSAList = STR(@VM,5)
END
Set_Property(@WINDOW:'.LSA_TABLE','LIST',LSAList)
Set_Property(@WINDOW:'.LS_TABLE','LIST',LSList)


RETURN


* * * * * * *
LSTableDC:
* * * * * * *


RowData = Get_Property(@WINDOW:'.LS_TABLE','ROWDATA')
CONVERT @FM TO @VM IN RowData

CurrPos = Get_Property(@WINDOW:'.LS_TABLE','SELPOS')
CurrCol = CurrPos<1>
CurrRow = CurrPos<2>

MDataCurr = RowData<1,CurrCol>

BEGIN CASE
	CASE CurrCol = COL$REC_NO
		RecID = ''
	
		Option = Msg(@WINDOW,'','RECIPE_OPTIONS')						; * Select, Create New or Cancel
		BEGIN CASE
			CASE Option = 1
				RecID = Popup(@WINDOW,'','CHOOSE_RECIPE')					;* Select List
			CASE Option = 2
				IF MDataCurr = '' THEN
					Void = Start_Window( 'RECIPE', @WINDOW, '*Choosing', '', '' )
				END ELSE
					Void = Start_Window( 'RECIPE', @WINDOW, MDataCurr:'*CENTER', '', '' )
				END
			CASE 1
				RETURN
		END CASE
		
		
		IF RecID NE '' THEN
			oaParms = RecID:@RM:@WINDOW:'.LS_TABLE':@RM:COL$REC_NO:@FM:CurrRow
			obj_Appwindow('LUValReturn',oaParms)
		END
		
		
	CASE CurrCol = COL$THK_UNITS
		TypeOver = ''
		TypeOver<PTITLE$>	= 'Thickness Units of Measurement'
		TypeOver<PDISPLAY$> = 'THICK':@SVM:'Thickness':@SVM:'Micron':@SVM:'æm':@VM
		TypeOver<PDISPLAY$> = TypeOver<PDISPLAY$>:'THICK':@SVM:'Thickness':@SVM:'Angstrom':@SVM:''
		
		Units = Popup(@WINDOW,TypeOver,'METROLOGY_UNITS')
		
		IF Units NE '' THEN
			oaParms = Units:@RM:@WINDOW:'.LS_TABLE':@RM:COL$THK_UNITS:@FM:CurrRow
			obj_Appwindow('LUValReturn',oaParms)
		END
		
	
	CASE CurrCol = COL$RES_UNITS
		TypeOver = ''
		TypeOver<PTITLE$>	= 'Resistance Units of Measurement'
		TypeOver<PDISPLAY$> = 'RES':@SVM:'Resistivity':@SVM:'Ohms.Cm':@SVM:'ê-cm':@VM
		TypeOver<PDISPLAY$> = TypeOver<PDISPLAY$>:'RES':@SVM:'Resistivity':@SVM:'Ohms/Sq':@SVM:'ê/Ü'
		
		Units = Popup(@WINDOW,TypeOver,'METROLOGY_UNITS')
		IF Units NE '' THEN
			oaParms = Units:@RM:@WINDOW:'.LS_TABLE':@RM:COL$RES_UNITS:@FM:CurrRow
			obj_Appwindow('LUValReturn',oaParms)
		END
	
	
	CASE CurrCol = COL$CON_UNITS
		TypeOver = ''
		TypeOver<PTITLE$>	= 'Concentration -  Units of Measurement'
		TypeOver<PDISPLAY$> = 'CONC':@SVM:'Concentration':@SVM:'Carriers.Cubic Centimeter':@SVM:'cm-3'
		
		
		TypeOver<PINITSELECT$> = 1
		Units = Popup(@WINDOW,TypeOver,'METROLOGY_UNITS')
		IF Units NE '' THEN
			oaParms = Units:@RM:@WINDOW:'.LS_TABLE':@RM:COL$CON_UNITS:@FM:CurrRow
			obj_Appwindow('LUValReturn',oaParms)
		END
	
	
	CASE CurrCol = COL$CRES_UNITS
		TypeOver = ''
		TypeOver<PTITLE$>	= 'Mercury Probe -  Units of Measurement'
		TypeOver<PDISPLAY$> = 'CRES':@SVM:'HgCvResistivity':@SVM:'Ohms.Cm':@SVM:'ê-cm'
		
		TypeOver<PINITSELECT$> = 1
		Units = Popup(@WINDOW,TypeOver,'METROLOGY_UNITS')
		IF Units NE '' THEN
			oaParms = Units:@RM:@WINDOW:'.LS_TABLE':@RM:COL$CRES_UNITS:@FM:CurrRow
			obj_Appwindow('LUValReturn',oaParms)
		END
		
		
END CASE


RETURN


* * * * * * *
LSATableDC:
* * * * * * *
RowData = Get_Property(@WINDOW:'.LSA_TABLE','ROWDATA')
CONVERT @FM TO @VM IN RowData

CurrPos = Get_Property(@WINDOW:'.LSA_TABLE','SELPOS')
CurrCol = CurrPos<1>
CurrRow = CurrPos<2>

MDataCurr = RowData<1,CurrCol>


BEGIN CASE
	CASE CurrCol = COL$THK_MEASURE
		
		MType = 'THICK'
		MDesc = 'Thickness'
		
		MDataNew = Dialog_Box( 'PROD_SPEC_SI4', @WINDOW, MDataCurr:CHAR(245):MType:CHAR(245):' ':MDesc:CHAR(245):'CENTER' )
		IF MDataNew NE '' AND MDataNew NE MDataCurr THEN
			Set_Property(@WINDOW:'.LSA_TABLE','CELLPOS',MDataNew,COL$THK_MEASURE:@FM:CurrRow)
		END

	CASE CurrCol = COL$RES_MEASURE
	
		MType = 'RES'
		MDesc = 'Resistivity'
		
		MDataNew = Dialog_Box( 'PROD_SPEC_SI4', @WINDOW, MDataCurr:CHAR(245):MType:CHAR(245):' ':MDesc:CHAR(245):'CENTER' )
		IF MDataNew NE '' AND MDataNew NE MDataCurr THEN
			Set_Property(@WINDOW:'.LSA_TABLE','CELLPOS',MDataNew,COL$RES_MEASURE:@FM:CurrRow)
		END

	CASE CurrCol = COL$CON_MEASURE
		
		MType = 'CON'
		MDesc = 'Concentration'
		
		MDataNew = Dialog_Box( 'PROD_SPEC_SI4', @WINDOW, MDataCurr:CHAR(245):MType:CHAR(245):' ':MDesc:CHAR(245):'CENTER' )
		IF MDataNew NE '' AND MDataNew NE MDataCurr THEN
			Set_Property(@WINDOW:'.LSA_TABLE','CELLPOS',MDataNew,COL$CON_MEASURE:@FM:CurrRow)
		END
	
	CASE CurrCol = COL$CRES_MEASURE
	
		MType = 'RCON'
		MDesc = 'Concentration Resistance'
		
		MDataNew = Dialog_Box( 'PROD_SPEC_SI4', @WINDOW, MDataCurr:CHAR(245):MType:CHAR(245):' ':MDesc:CHAR(245):'CENTER' )
		IF MDataNew NE '' AND MDataNew NE MDataCurr THEN
			Set_Property(@WINDOW:'.LSA_TABLE','CELLPOS',MDataNew,COL$CRES_MEASURE:@FM:CurrRow)
		END
	
END CASE


RETURN



* * * * * * *
LSAPC:
* * * * * * *

CtrlEntID = 'PROD_SPEC_SI.LSA_TABLE'

LSAList		= Get_Property(CtrlEntID,'LIST')
LSAInArray	= Get_Property(CtrlEntID,'INVALUE')
LSList		= Get_Property('PROD_SPEC_SI.LS_TABLE','LIST')


PrevSelPos	= Get_Property(CtrlEntId,"PREVSELPOS")
PrevCol 	= PrevSelPos<1>
PrevRow 	= PrevSelPos<2>

CurrPos 	= Get_Property(CtrlEntId,'SELPOS')
CurrCol		= CurrPos<1>
CurrRow		= CurrPos<2>


* LostFocus checks 

LSIds = LSAInArray<COL$LS_ID>

* This section maintains the Layer Set ID column

GoodLines = 0
LineCnt = COUNT(LSAList,@FM) + (LSAList NE '')

LOOP
	TestLine = LSAList[-1,'B':@FM]
	TestLine = FIELD(TestLine,@VM,2,14)
UNTIL TestLine NE STR(@VM,13) 
	LSAList = DELETE(LSAList,LineCnt,0,0)
	Set_Property(CtrlEntID,'INVALUE','',COL$LS_ID:@FM:LineCnt)
	LineCnt -= 1
REPEAT


LSArray = ''
FOR I = 1 TO LineCnt
	BEGIN CASE
		CASE I = 1
			Layer = 'L1'
		
		CASE I = 2 
			IF LineCnt = 3 THEN
				Layer = 'L2'
			END ELSE
				Layer = '2'
			END
			
		CASE I = 3 ; Layer = '2'
		CASE 1 ; Layer = I-1
	END CASE
	
	IF LSAInArray<COL$LS_ID> NE Layer THEN
		Set_Property(CtrlEntID,'INVALUE',Layer,COL$LS_ID:@FM:I)
	END
	
NEXT I	


IF LSAList<PrevRow,PrevCol> NE '' THEN
	
	BEGIN CASE
	
		CASE PrevCol = COL$DOPANT
		
			SpecDopant = LSAList<PrevRow,PrevCol>
			RecipeID = LSList<PrevRow,COL$REC_NO>
			
			IF SpecDopant NE '' AND RecipeID NE '' THEN
				IF PrevRow = 1 THEN
					RecipeDopant = XLATE( 'RECIPE', RecipeID, RECIPE_EPI_DOPANT$, 'X' )
				END ELSE
					RecLayInfo = XLATE( 'RECIPE', RecipeID, RECIPE_LAYER_INFO$, 'X' )	;* Retrives rathole data for layers > 1
					RecipeDopant = RecLayInfo<PrevRow - 1,RecLEpiDopant$>      
				END
				
				IF SpecDopant NE RecipeDopant THEN
					ErrMsg('Dopant entered ':Quote(SpecDopant):' does not match the dopant on the recipe ':QUOTE(RecipeDopant):'.')
					Set_Property(CtrlEntID,"SELPOS",PrevSelPos)
					Set_Property(CtrlEntID,'INVALUE','',PrevSelPos)			;* Clear entered field
				END
			END
			
	END CASE	
END
		
		
* Gotfocus checks
			
IF CurrCol = COL$LS_ID THEN
	Set_Property(CtrlEntId,'SELPOS',CurrCol + 1:@FM:CurrRow)
END	
			
RETURN



* * * * * * *
LSPC:
* * * * * * *

CtrlEntID = 'PROD_SPEC_SI.LS_TABLE'

LSList		= Get_Property(CtrlEntID,'LIST')
LSInArray	= Get_Property(CtrlEntID,'INVALUE')
LSAList		= Get_Property('PROD_SPEC_SI.LSA_TABLE','LIST')

PrevSelPos	= Get_Property(CtrlEntId,"PREVSELPOS")
PrevCol 	= PrevSelPos<1>
PrevRow 	= PrevSelPos<2>

CurrPos 	= Get_Property(CtrlEntId,'SELPOS')
CurrCol		= CurrPos<1>
CurrRow		= CurrPos<2>


* LostFocus checks 


LSIds = LSInArray<COL$LS_ID>

* This section maintains the Layer Set ID column

GoodLines = 0
LineCnt = COUNT(LSList,@FM) + (LSList NE '')

LOOP
	TestLine = LSList[-1,'B':@FM]
	TestLine = FIELD(TestLine,@VM,2,14)
UNTIL TestLine NE STR(@VM,13) 
	LSList = DELETE(LSList,LineCnt,0,0)
	Set_Property(CtrlEntID,'INVALUE','',COL$LS_ID:@FM:LineCnt)
	LineCnt -= 1
REPEAT


LSArray = ''
FOR I = 1 TO LineCnt
	BEGIN CASE
		CASE I = 1
			Layer = 'L1'
		
		CASE I = 2 
			IF LineCnt = 3 THEN
				Layer = 'L2'
			END ELSE
				Layer = '2'
			END
			
		CASE I = 3 ; Layer = '2'
		CASE 1 ; Layer = I-1
	END CASE
	
	IF LSInArray<COL$LS_ID> NE Layer THEN
		Set_Property(CtrlEntID,'INVALUE',Layer,COL$LS_ID:@FM:I)
	END
	
NEXT I	
	
BEGIN CASE

	CASE PrevCol = COL$REC_NO
	
		SpecDopant	= LSAList<PrevRow,COL$DOPANT>
		RecipeID	= LSList<PrevRow,COL$REC_NO>
		RecipeName	= LSList<PrevRow,COL$REC_DESC>
		
		IF SpecDopant NE '' AND RecipeID NE '' THEN
			IF PrevRow = 1 THEN
				RecipeDopant = XLATE( 'RECIPE', RecipeID, RECIPE_EPI_DOPANT$, 'X' )
			END ELSE
				RecLayInfo = XLATE( 'RECIPE', RecipeID, RECIPE_LAYER_INFO$, 'X' )	;* Retrives rathole data for layers > 1
				RecipeDopant = RecLayInfo<PrevRow - 1,RecLEpiDopant$>      
			END
			
			IF SpecDopant NE RecipeDopant THEN
				ErrMsg('Dopant entered ':Quote(SpecDopant):' does not match the dopant on the recipe ':QUOTE(RecipeDopant):'.')
				Set_Property(CtrlEntID,"SELPOS",PrevSelPos)
				Set_Property(CtrlEntID,'INVALUE','',PrevSelPos)						;* Clear entered field
			END
		END
		
		IF SpecDopant = '' AND RecipeID NE '' THEN
			IF PrevRow = 1 THEN
				RecipeDopant = XLATE( 'RECIPE', RecipeID, RECIPE_EPI_DOPANT$, 'X' )
			END ELSE
				RecLayInfo = XLATE( 'RECIPE', RecipeID, RECIPE_LAYER_INFO$, 'X' )	;* Retrives rathole data for layers > 1
				RecipeDopant = RecLayInfo<PrevRow - 1,RecLEpiDopant$>      
			END
			
			Set_Property('PROD_SPEC_SI.LSA_TABLE','INVALUE',RecipeDopant,COL$DOPANT:@FM:PrevRow)	;* Sets null default for Dopant
			
			
		END
		
		IF RecipeID NE '' THEN
			RecipeName = XLATE( 'RECIPE', RecipeId, RECIPE_RECIPE_NAME$, 'X' )
		END ELSE
			RecipeName = ''
		END
 			
 		Set_Property(CtrlEntID,"SELPOS",COL$REC_DESC:@FM:PrevRow)
		Set_Property(CtrlEntID,'INVALUE',RecipeName,COL$REC_DESC:@FM:PrevRow)
			
		
		
		
	CASE PrevCol = COL$THK_MIN OR PrevCol = COL$THK_MAX
		ThickMin = LSInArray<COL$THK_MIN,PrevRow>
		ThickMax = LSInArray<COL$THK_MAX,PrevRow>
		
		IF ThickMin NE '' AND ThickMax NE '' THEN
			IF ThickMin > ThickMax THEN 
				ErrMsg('Thickness Minimum is greater than the Thickness Maximum in ':LSInArray<COL$LS_ID,PrevRow>:'.')
				Set_Property(CtrlEntID,'SELPOS',PrevPos)
			END
		END
		
	CASE PrevCol = COL$RES_MIN OR PrevCOl = COL$RES_MAX
		ResMin	= LSInArray<COL$RES_MIN,PrevRow>
		ResMax	= LSInArray<COL$RES_MAX,PrevRow>
		
		IF ResMin NE '' AND ResMax NE '' THEN
			IF ResMin > ResMax THEN 
				ErrMsg('Resistance Minimum is greater than the Resistance Maximum in ':LSInArray<COL$LS_ID,PrevRow>:'.')
				Set_Property(CtrlEntID,'SELPOS',PrevPos)
			END
		END
		
	CASE PrevCol = COL$CON_MIN OR PrevCol = COL$CON_MAX
		NULL
		
	CASE PrevCol = COL$CRES_MIN OR PrevCol = COL$CRES_MAX
		CResMin	= LSInArray<COL$CRES_MIN>
		CResMax	= LSInArray<COL$CRES_MAX>
		
		IF CResMin NE '' AND CResMax NE '' THEN
			IF CResMin > CResMax THEN 
				ErrMsg('CResistance Minimum is greater than the CResistance Maximum in ':LSInArray<COL$LS_ID,PrevRow>:'.')
				Set_Property(CtrlEntID,'SELPOS',PrevPos)
			END
		END
		
END CASE	

		
IF CurrCol = COL$LS_ID THEN
	Set_Property(CtrlEntId,'SELPOS',CurrCol + 1:@FM:CurrRow)
END	

RETURN


* * * * * * *
LSTableDel:
* * * * * * *

CtrlEntID = 'PROD_SPEC_SI.LS_TABLE'

LSList		= Get_Property(CtrlEntID,'LIST')
LSInArray	= Get_Property(CtrlEntID,'INVALUE')
LSAList		= Get_Property('PROD_SPEC_SI.LSA_TABLE','LIST')

PrevSelPos	= Get_Property(CtrlEntId,"PREVSELPOS")
PrevCol 	= PrevSelPos<1>
PrevRow 	= PrevSelPos<2>

CurrPos 	= Get_Property(CtrlEntId,'SELPOS')
CurrCol		= CurrPos<1>
CurrRow		= CurrPos<2>


LSIds = LSInArray<COL$LS_ID>

* This section maintains the Layer Set ID column
GoodLines = 0
LineCnt = COUNT(LSList,@FM) + (LSList NE '')

LOOP
	TestLine = LSList[-1,'B':@FM]
	TestLine = FIELD(TestLine,@VM,2,14)
UNTIL TestLine NE STR(@VM,13) 
	LSList = DELETE(LSList,LineCnt,0,0)
	Set_Property(CtrlEntID,'INVALUE','',COL$LS_ID:@FM:LineCnt)
	LineCnt -= 1
REPEAT

RETURN


* * * * * * *
LSATableDel:
* * * * * * *

CtrlEntID = 'PROD_SPEC_SI.LSA_TABLE'

LSList		= Get_Property(CtrlEntID,'LIST')
LSInArray	= Get_Property(CtrlEntID,'INVALUE')
LSAList		= Get_Property('PROD_SPEC_SI.LSA_TABLE','LIST')

PrevSelPos	= Get_Property(CtrlEntId,"PREVSELPOS")
PrevCol 	= PrevSelPos<1>
PrevRow 	= PrevSelPos<2>

CurrPos 	= Get_Property(CtrlEntId,'SELPOS')
CurrCol		= CurrPos<1>
CurrRow		= CurrPos<2>

LSIds = LSInArray<COL$LS_ID>

* This section maintains the Layer Set ID column

GoodLines = 0
LineCnt = COUNT(LSList,@FM) + (LSList NE '')

LOOP
	TestLine = LSList[-1,'B':@FM]
	TestLine = FIELD(TestLine,@VM,2,14)
UNTIL TestLine NE STR(@VM,13) 
	LSList = DELETE(LSList,LineCnt,0,0)
	Set_Property(CtrlEntID,'INVALUE','',COL$LS_ID:@FM:LineCnt)
	LineCnt -= 1
REPEAT

RETURN


* * * * * * *
Save:
* * * * * * *

* New completeness check added on 20 JAN 2011 by JCH

LSList = Get_Property(@WINDOW:'.LS_TABLE','LIST')

LineCnt = COUNT(LSList,@FM) + (LSList NE '')

FOR I = 1 TO LineCnt

	IF LSList<I,COL$LS_ID> NE '' THEN
	
		ThickMin = LSList<I,COL$THK_MIN>	;	ThickMax = LSList<I,COL$THK_MAX>	;	ThickUnits = LSList<I,COL$THK_UNITS>
		
		IF ThickMin NE '' OR ThickMax NE '' THEN
			 IF ThickMin = '' OR ThickMax = '' OR ThickUnits = '' THEN
				ErrMsg('Incomplete Thickness Specification on Layer Set ':LSList<I,COL$LS_ID>:'...')
				RETURN
			END
		END
		
		ResMin = LSList<I,COL$RES_MIN>	;	ResMax = LSList<I,COL$RES_MAX>	;	ResUnits = LSList<I,COL$RES_UNITS>

		IF ResMin NE '' OR ResMax NE '' THEN
			 IF ResMin = '' OR ResMax = '' OR ResUnits = '' THEN
				ErrMsg('Incomplete Resistivity Specification on Layer Set ':LSList<I,COL$LS_ID>:'...')
				RETURN
			 END
		END
		
		ConMin = LSList<I,COL$CON_MIN>	;	ConMax = LSList<I,COL$CON_MAX>	;	ConUnits = LSList<I,COL$CON_UNITS>
		
		IF ConMin NE '' OR ConMax NE '' THEN
			 IF ConMin = '' OR ConMax = '' OR ConUnits = '' THEN
				ErrMsg('Incomplete Concentration Specification on Layer Set ':LSList<I,COL$LS_ID>:'...')
				RETURN
			 END
		END
		
		CResMin = LSList<I,COL$CRES_MIN>	;	CResMax = LSList<I,COL$CRES_MAX>	;	CResUnits = LSList<I,COL$CRES_UNITS>
		
		IF CResMin NE '' OR CResMax  NE '' THEN
			 IF CResMin = '' OR CResMax  = '' OR CResUnits = '' THEN
				ErrMsg('Incomplete CResistivity Specification on Layer Set ':LSList<I,COL$LS_ID>:'...')
				RETURN
			END
		END

	END	;* End of check for Layer Set ID
NEXT I


* This needs to end up setting @EpiInfo on the window

LSAArray	= Get_Property(@WINDOW:'.LSA_TABLE','INVALUE')
LSArray		= Get_Property(@WINDOW:'.LS_TABLE','INVALUE')
Product		= Get_Property(@WINDOW:'.SUB_PRODUCTS','TEXT')

IF Product NE '' THEN
	CurProducts = xlate( 'LISTBOX_CONFIG', 'PRODUCTS', '', 'X' )
	LOCATE Product IN CurProducts USING @VM SETTING Ppos ELSE
		MsgInfo = ''
		ErrMsg('Product ':QUOTE(Product):' is not valid.')
		
		RETURN
	END
END ELSE
	ErrMsg('You must select a product.')
	
	RETURN
END


L1RecipeID = LSArray<COL$REC_NO,1>

IF L1RecipeID NE '' THEN

	RecipePSNs	= XLATE( 'RECIPE', L1RecipeID, RECIPE_PROD_SPEC_IDS$, 'X' )
	CurPSN		= Get_Property( 'PROD_SPEC.PROD_SPEC_ID', 'TEXT' )

	LOCATE CurPSN IN RecipePSNs USING @VM SETTING FPos ELSE
		MsgInfo = ''
		MText   = 'This PSN ':quote(CurPSN):' is not set up in recipe ':quote(L1RecipeID)
		MText  := " with it's own recipe limits.  If this PSN is activated and goes through the"
		MText  := ' system without these limits, the system will use the top row limits in the'
		MText  := ' recipe.  Please notify an engineer to handle this issue.'
		MsgInfo<mtext$> = MText       
		MsgInfo<micon$> = '!'
		Msg( '', MsgInfo )
	END
END


SubPreClean = Get_Property( @WINDOW:'.SUB_PRE_CLEAN', 'TEXT' )

IF INDEX( SubPreClean,'Akrion', 1 ) THEN
 	PreAkrionRecipe = Get_Property( @WINDOW:'.PRECLEAN_AKRIONRECIPES', 'TEXT' )
	IF PreAkrionRecipe = '' THEN
		MsgInfo = ''
		ErrMsg('You must select a pre clean akrion recipe...')
		
		RETURN
	END
END

SubPostClean = Get_Property( @WINDOW:'.SUB_POST_CLEAN', 'TEXT' )
IF INDEX( SubPostClean, 'Akrion', 1 ) THEN
	PostAkrionRecipe = Get_Property( @WINDOW:'.POSTCLEAN_AKRIONRECIPES', 'TEXT' )
	IF PostAkrionRecipe = '' THEN
		ErrMsg('You must select a post clean akrion recipe...')
		
		RETURN
	END
END

Result = 1

SaveEpiInfo = ''

LSIDs = ''

FOR I = 1 TO 9
	LSID = LSArray<COL$LS_ID,I>
UNTIL LSID = ''

	SaveEpiInfo<I,QSEpiRecipe$>			= LSArray<COL$REC_NO,I>
	SaveEpiInfo<I,QSEpiRecipeName$>		= LSArray<COL$REC_DESC,I>
	SaveEpiInfo<I,QSEpiConcMinThick$>	= LSArray<COL$CON_MIN,I>
	SaveEpiInfo<I,QSEpiConcMaxThick$>	= LSArray<COL$CON_MAX,I>
	SaveEpiInfo<I,QSEpiConcUnits$>		= LSArray<COL$CON_UNITS,I>
	SaveEpiInfo<I,QSEpiResMinThick$> 	= LSArray<COL$RES_MIN,I>
	SaveEpiInfo<I,QSEpiResMaxThick$> 	= LSArray<COL$RES_MAX,I>
	SaveEpiInfo<I,QSEpiResUnits$>		= LSArray<COL$RES_UNITS,I>
	SaveEpiInfo<I,QSEpiMinThick$>		= LSArray<COL$THK_MIN,I>
	SaveEpiInfo<I,QSEpiMaxThick$>		= LSArray<COL$THK_MAX,I>
	SaveEpiInfo<I,QSEpiThickUnits$> 	= LSArray<COL$THK_UNITS,I>
	SaveEpiInfo<I,QSEpiCresMin$>		= LSArray<COL$CRES_MIN,I>
	SaveEpiInfo<I,QSEpiCresMax$>		= LSArray<COL$CRES_MAX,I>
	SaveEpiInfo<I,QSEpiCresUnits$>		= LSArray<COL$CRES_UNITS,I>
	SaveEpiInfo<I,QSEpiCresPhaseMin$>   = LSArray<COL$CRES_PHASE_MIN,I>
	SaveEpiInfo<I,QSEpiDopant$>			= LSAArray<COL$DOPANT,I>
	SaveEpiInfo<I,QSEpiThickMeasure$>	= LSAArray<COL$THK_MEASURE,I>
	SaveEpiInfo<I,QSEpiResMeasure$>		= LSAArray<COL$RES_MEASURE,I>
	SaveEpiInfo<I,QSEpiConcMeasure$>	= LSAArray<COL$CON_MEASURE,I>	
	SaveEpiInfo<I,QSEpiCresMeasure$>	= LSAArray<COL$CRES_MEASURE,I>	
	
NEXT I


CONVERT @FM TO CHAR(248) IN SaveEpiInfo

Set_Property(@WINDOW,'@EpiInfoTest',SaveEpiInfo)

Controls		= Get_Property( @WINDOW, '@SubControls' )
SubstrateInfo	= Get_Property( Controls, 'INVALUE' )

CONVERT @RM TO @VM IN SubstrateInfo
SWAP @TM WITH CRLF$ IN SubstrateInfo

Controls = Get_Property( @WINDOW, '@AddlControls' )
AddlInfo = Get_Property( Controls, 'INVALUE' )

CONVERT @RM TO @VM IN AddlInfo
SWAP @TM WITH CRLF$ IN AddlInfo

Controls	= Get_Property( @WINDOW, '@NDControls' )
NDInfo		= Get_Property( Controls, 'INVALUE' )

CONVERT @RM TO @VM IN NDInfo

Controls	= Get_Property( @WINDOW, '@PPControls' )
PPInfo		= Get_Property( Controls, 'INVALUE' )

CONVERT @RM TO @VM IN PPInfo


ReturnData = SubstrateInfo:CHAR(244):SaveEpiInfo:CHAR(244):AddlInfo:CHAR(244):NDInfo:CHAR(244):PPInfo


Set_Property(@WINDOW,'@ReturnData', ReturnData)

Result = ReturnData

RETURN


