FUNCTION remove, str, ind
	;
	; check the array type
	;
	if size(str, /type) ne 7 then return, 'error: array must be strarray'
	num_str = n_elements(str)

	num_ind = n_elements(ind)
	;
	; index out of range
	;
	if num_ind gt num_str then return, 'error: index to remove is out of range'
	;
	; more than one to remove, recursion
	;
	oriStr = str
	if num_ind gt 1 then begin
		for i=0, num_ind-1 do begin
			if ind[i] lt 0 or $
			   ind[i] gt num_str-1 then return, $
			   		'error: index to remove must between n_elements(str)-1)'
			rInd = where(oriStr[ind[i]] eq str)
			str = pc_str_remove(str, rInd)
		endfor
		return, str
	endif
	;
	; only one, go go go...
	;
	if ind lt 0 or $
	   ind gt num_str-1 then return, $
	   		'error: index to remove must between n_elements(str)-1)'
	;
	; only one elements
	;
	if num_str eq 1 then return, ''
	;
	; remove the first one
	;
	if ind eq 0 then return, str[1:num_str-1]
	;
	; remove the last one
	;
	if ind eq num_str-1 then return, str[0:num_str-2]
	;
	; in the middle, kick his ass.
	;
	return, [str[0:ind-1],str[ind+1:num_str-1]]
END
;+
;dele select file
;+
PRO sesCartoon::deleFile , id, index
	COMPILE_OPT IDL2

	if widget_info(id, /type) ne 6 then return ; not a list widget

	if index[0] eq -1 then return	; index out of range

	widget_control, id, get_uvalue=listItems

	listItems = remove(listItems, index)

	num_list = n_elements(listItems)

	if index[0] lt num_list then begin
		sel = index[0]
	endif else sel = index[0] - 1

	widget_control, id, set_value=listItems, set_uvalue=listItems, set_list_select=sel

END

PRO sesCartoon::acpoleImage , a1 , a2 , crfct
	COMPILE_OPT IDL2

;	imageSize=size(a1,/Dimensions)
;	nx=imageSize[0]
;	ny=imageSize[1]
;	a11=fft(fft(a1,1)*conj(fft(a2,1)),-1)
;	a12=abs(a11*conj(a11))
;	fmax=max(a12,i)
;	shx=i mod nx
;	shy=i/nx
;	if(shx gt nx/2) then shx=shx-nx
;	if(shy gt ny/2) then shy=shy-ny

	imageDim = SIZE (a1 , /Dimensions)
	dim2 = SIZE (a2 , /Dimensions)
	nx = imageDim[0]
	ny = imageDim[1]
	;;; Compute the crosscorrelation function.
	crfct = FFT ( a1, -1 )
	crfct = CONJ ( crfct )
	crfct = crfct * FFT ( a2, -1 )
	crfct = FFT (crfct, 1 )
	crfct = FLOAT ( crfct )
	;;; Compute the shifts with respect to IMG1.
	mx = MAX ( crfct, index )
	x = index MOD nx
	IF x GT ( nx / 2 ) THEN x = x - nx
	y = index / nx
	IF y GT ( ny / 2 ) THEN y = y - ny

	   ;;; Shift crosscorelation function from butterfly to centered format.
	crfct = SHIFT ( crfct, nx / 2, ny / 2 )

	RETURN

END
;+
;press draw
;+
PRO sesCartoon::PressDraw , bmpArr , type
	COMPILE_OPT IDL2
	draw = [self.drawOpen,self.drawSave , $
	        self.drawPlay,self.drawBack , $
	        self.drawStop,self.drawHead   ]
	WSet, draw[type]
	TV, Reform(bmpArr, [3,20,20]), /True
	OI = [0,15,3,6,9,12]
	FOR i = 0 , 5 DO BEGIN
		IF type NE i THEN BEGIN
			self->Draw , draw[i] , self.bmpArr[OI[i],*,*,*]
			self.oClick[i] = 0
		ENDIF ELSE BEGIN
			self.oClick[i] = 1
		ENDELSE
	ENDFOR
END
;+
;draw
;+
PRO sesCartoon::Draw , draw , bmpArr
	COMPILE_OPT IDL2
	WSet, draw
	TV, Reform(bmpArr, [3,20,20]), /True
END
;+
;save cartoon
;+
PRO sesCartoon::SaveCartoon
	COMPILE_OPT IDL2
	oSystem = self.oSystem
	CASE !VERSION.OS_FAMILY of
        'unix': BEGIN
            fileName=Dialog_Pickfile(/write,TITLE='select save path'    , $
	   								DEFAULT_EXTENSION='*.mpeg'          , $
	   								/OVERWRITE_PROMPT                   , $
	        						path=self.RootDir                   , $
	        						filter='*.mpeg')
        END
        'Windows': BEGIN
            fileName=Dialog_Pickfile(/write,TITLE='select save path'    , $
	   								DEFAULT_EXTENSION='*.mpeg'          , $
	   								/OVERWRITE_PROMPT                   , $
	        						path=self.RootDir                   , $
	        						filter='*.mpeg')
        END
    	ELSE:
    ENDCASE
	self.oWindow -> Draw, self.oView
	IF fileName NE '' THEN BEGIN
		CASE !VERSION.OS_FAMILY of
		    'unix': begin
		     	unix:
			    dims = size((*(self.Data))[0,*,*], /dimensions)

			    ; set the necessary property of IDLgrMpeg

			    oMPEG = obj_new('IDLgrMPEG')
			    oMPEG->setproperty, $
				   	   FILENAME=fileName, $ ; path of saving
					   dimensions=[dims[1],dims[2]], $ ; dimesions of mpeg, the same as data dims
					   FRAME_RATE=2, $ ; 24F/Sec, international standard
					   FORMAT=0, $ ; Mpeg1
					   IFRAME_GAP=25, $ ; frame gap, close to the frame rate
					   quality=100 ; quality of mpeg, better, larger
				;count frame
				gaps = FltArr(self.fileNumber)
				gaps[*] = 1./(self.CartoonRate)
				frameGaps = fix(gaps*24+0.5)
				frameBegins = 0	; the begining position of each frame
				FOR i=1, N_Elements(gaps)-1 DO BEGIN
					FOR j=0, i-1 DO BEGIN
						gap = frameBegins[i-1] + frameGaps[j]
						frameBegins = [frameBegins, gap+1]
					ENDFOR
				ENDFOR
				;
				; put datas to IDLgrMPEG
				;
				numbers = self.fileNumber
				t = 0
				IF numbers LT 35 THEN proValue = Fix(35/Double(numbers))
				IF numbers GT 35 THEN proValue = 35/Double(numbers)
				oSystem.oProcess->mapBase , 1
			    FOR i=0,self.fileNumber-1 DO BEGIN
			    	IF round(self.Process+proValue) LT 32 THEN BEGIN
						FOR j = self.Process , round(self.Process+proValue) DO BEGIN
							oSystem.oProcess->DoProcess , j
						ENDFOR
						self.Process = round(self.Process+proValue)
					ENDIF
					oMPEG-> Put, Reform((*(self.Data))[i,*,*]),	frameBegins[i]
				ENDFOR
				oSystem.oProcess->DoProcess , 35
				;
				; fill the last frame position of the movie
				;
				oMPEG-> Put, Reform((*(self.Data))[i-1,*,*]) , $
				             frameBegins[i-1]+frameGaps[i-1] ;, /order
				;
				; save it
				;
				; 24 frames fit one second, cast around 7 seconds
				oMPEG-> Save

				Obj_Destroy, oMPEG
				oSystem.oProcess->mapBase , 0
	        END
	        'Windows': BEGIN
	        	dims = size((*(self.Data))[0,*,*], /dimensions)

			    ; set the necessary property of IDLgrMpeg

			    oMPEG = obj_new('IDLgrMPEG')
			    oMPEG->setproperty, $
				   	   FILENAME=fileName, $ ; path of saving
					   dimensions=[dims[1],dims[2]], $ ; dimesions of mpeg, the same as data dims
					   FRAME_RATE=2, $ ; 24F/Sec, international standard
					   FORMAT=0, $ ; Mpeg1
					   IFRAME_GAP=25, $ ; frame gap, close to the frame rate
					   quality=100 ; quality of mpeg, better, larger

				;count frame
				gaps = FltArr(self.fileNumber)
				gaps[*] = 1./(self.CartoonRate)
				frameGaps = fix(gaps*24+0.5)
				frameBegins = 0	; the begining position of each frame
				FOR i=1, N_Elements(gaps)-1 DO BEGIN
					FOR j=0, i-1 DO BEGIN
						gap = frameBegins[i-1] + frameGaps[j]
						frameBegins = [frameBegins, gap+1]
					ENDFOR
				ENDFOR
				;
				; put datas to IDLgrMPEG
				;
				numbers = self.fileNumber
				t = 0
				IF numbers LT 35 THEN proValue = Fix(35/Double(numbers))
				IF numbers GT 35 THEN proValue = 35/Double(numbers)
				oSystem.oProcess->mapBase , 1
			    FOR i=0,self.fileNumber-1 DO BEGIN
			    	IF round(self.Process+proValue) LT 32 THEN BEGIN
						FOR j = self.Process , round(self.Process+proValue) DO BEGIN
							oSystem.oProcess->DoProcess , j
						ENDFOR
						self.Process = round(self.Process+proValue)
					ENDIF
					oMPEG-> Put, Reform((*(self.Data))[i,*,*]),	frameBegins[i]
				ENDFOR
				oSystem.oProcess->DoProcess , 35
				;
				; fill the last frame position of the movie
				;
				oMPEG-> Put, Reform((*(self.Data))[i-1,*,*]) , $
				             frameBegins[i-1]+frameGaps[i-1] ;, /order
				;
				; save it
				;
				; 24 frames fit one second, cast around 7 seconds
				oMPEG-> Save

				Obj_Destroy, oMPEG
				oSystem.oProcess->mapBase , 0
	        END
	    ELSE:
	    ENDCASE
	ENDIF
END
;+
;adjust bmp file
;+
PRO sesCartoon::Adjust , type = type , UName = UName
	COMPILE_OPT IDL2
	CASE UName OF
		'open':BEGIN
			CASE type OF
				0:BEGIN
					IF self.oClick[0] NE 1 THEN BEGIN
						self->Draw , self.drawOpen , self.bmpArr[1,*,*,*]
					ENDIF
				END
				1:BEGIN
					self->Draw , self.drawOpen , self.bmpArr[0,*,*,*]
				END
				2:BEGIN
					self->PressDraw , self.bmpArr[2,*,*,*] , 0
					self->OpenFile
				END
			ELSE:
			ENDCASE
		END
;		'dele':BEGIN
;			CASE type OF
;				0:BEGIN
;					IF self.oClick[1] NE 1 THEN BEGIN
;						self->Draw , self.drawDele , self.bmpArr[16,*,*,*]
;					ENDIF
;				END
;				1:BEGIN
;					self->Draw , self.drawDele , self.bmpArr[15,*,*,*]
;				END
;				2:BEGIN
;					self->PressDraw , self.bmpArr[17,*,*,*] , 1
;;					sel = Widget_Info(self.list, /list_select)
;;					self->deleFile, self.list, sel
;				END
;			ELSE:
;			ENDCASE
;		END
		'save':BEGIN
			CASE type OF
				0:BEGIN
					IF self.oClick[6] NE 1 THEN BEGIN
						self->Draw , self.drawSave , self.bmpArr[16,*,*,*]
					ENDIF
				END
				1:BEGIN
					self->Draw , self.drawSave , self.bmpArr[15,*,*,*]
				END
				2:BEGIN
					self->PressDraw , self.bmpArr[17,*,*,*] , 1
					IF self.type EQ 1 THEN BEGIN
						self->SaveCartoon
					ENDIF
				END
			ELSE:
			ENDCASE
		END
		'play':BEGIN
			CASE type OF
				0:BEGIN
					IF self.oClick[2] NE 1 THEN BEGIN
						self->Draw , self.drawPlay , self.bmpArr[4,*,*,*]
					ENDIF
				END
				1:BEGIN
					IF self.oClick[2] NE 1 THEN BEGIN
						self->Draw , self.drawPlay , self.bmpArr[3,*,*,*]
					ENDIF
				END
				2:BEGIN
					self->PressDraw , self.bmpArr[5,*,*,*] , 2
					IF self.type EQ 1 THEN BEGIN
						self.oWindow->SetEventMask, TIMER_EVENTS=1
						Widget_Control,self.backBu,Sensitive = 0
						Widget_Control,self.headBu,Sensitive = 0
					ENDIF
				END
			ELSE:
			ENDCASE
		END
		'back':BEGIN
			CASE type OF
				0:BEGIN
					IF self.oClick[3] NE 1 THEN BEGIN
						self->Draw , self.drawBack , self.bmpArr[7,*,*,*]
					ENDIF
				END
				1:BEGIN
					self->Draw , self.drawBack , self.bmpArr[6,*,*,*]

				END
				2:BEGIN
					self->PressDraw , self.bmpArr[8,*,*,*] , 3
					IF self.type EQ 1 THEN BEGIN
						self.observer->GetProperty, INC=advance
				        self.observer->SetProperty, INC= -advance
				        self.observer->OnTimer, self.oWindow
				        self.observer->SetProperty, INC=advance
				    ENDIF
				END
				3:BEGIN
					self->Draw , self.drawBack , self.bmpArr[6,*,*,*]
				END
			ELSE:
			ENDCASE
		END
		'stop':BEGIN
			CASE type OF
				0:BEGIN
					IF self.oClick[4] NE 1 THEN BEGIN
						self->Draw , self.drawStop , self.bmpArr[10,*,*,*]
					ENDIF
				END
				1:BEGIN
					IF self.oClick[4] NE 1 THEN BEGIN
						self->Draw , self.drawStop , self.bmpArr[9,*,*,*]
					ENDIF
				END
				2:BEGIN
					self->PressDraw , self.bmpArr[11,*,*,*] , 4
					IF self.type EQ 1 THEN BEGIN
						self.oWindow->SetEventMask, TIMER_EVENTS=0
	        			self.oWindow->Draw, self.oView
	        			Widget_Control,self.backBu,Sensitive = 1
						Widget_Control,self.headBu,Sensitive = 1
					ENDIF
				END
			ELSE:
			ENDCASE
		END
		'head':BEGIN
			CASE type OF
				0:BEGIN
					IF self.oClick[5] NE 1 THEN BEGIN
						self->Draw , self.drawHead , self.bmpArr[13,*,*,*]
					ENDIF
				END
				1:BEGIN
					self->Draw , self.drawHead , self.bmpArr[12,*,*,*]

				END
				2:BEGIN
					self->PressDraw , self.bmpArr[14,*,*,*] , 5
					IF self.type EQ 1 THEN BEGIN
						self.observer->OnTimer, self.oWindow
					ENDIF
				END
				3:BEGIN
					self->Draw , self.drawHead , self.bmpArr[12,*,*,*]
				END
			ELSE:
			ENDCASE
		END
	ELSE:
	ENDCASE

END
;+
;read bmp image
;+
PRO sesCartoon::ReadBmp
	COMPILE_OPT IDL2
	sep = (self.oSystem).sep
	fileName = ['cartoon_1_1.bmp','cartoon_1_2.bmp','cartoon_1_3.bmp', $
	            'cartoon_2_1.bmp','cartoon_2_2.bmp','cartoon_2_3.bmp', $
	            'cartoon_3_1.bmp','cartoon_3_2.bmp','cartoon_3_3.bmp', $
	            'cartoon_4_1.bmp','cartoon_4_2.bmp','cartoon_4_3.bmp', $
	            'cartoon_5_1.bmp','cartoon_5_2.bmp','cartoon_5_3.bmp', $
	            'cartoon_6_1.bmp','cartoon_6_2.bmp','cartoon_6_3.bmp'  ]
	FOR i = 0 , N_Elements(fileName)-1 DO BEGIN
		bmp = Read_Image(self.RootDir + sep+'resource'+sep+'bitmap'+sep+'cartoon'+sep+fileName[i])
		self.bmpArr[i,*,*,*] = AdjustBmp(bmp, self.signColor, self.foreColor)
	ENDFOR

END
;+
;open file
;+
PRO sesCartoon::OpenFile
	COMPILE_OPT IDL2
	oSystem = self.oSystem
	sep = oSystem.sep
	filter = ['*.fit' , '*.dat']
	fileName=Dialog_Pickfile(title='Please choose cartoon file' , $
	                         filter=filter                    , $
	                         path=self.RootDir+sep+'data'	      , $
	                         /Multiple_Files )

	oSystem.oWindow->Draw,oSystem.oScene
    IF fileName[0] NE '' THEN BEGIN
		Numbers = N_Elements(fileName)
		IF Numbers GE 2 THEN BEGIN
			IF (fileName[0] NE '') THEN BEGIN
				fitData = ReadFitData(filename[0],fit_header)
				seg= Strmid(File_BaseName(filename[0]), 0, 1)
				number = ['L','Q','U']
				temp = Where(seg EQ number , count)
				IF count NE 0 THEN BEGIN
					fitData = Swap_Endian(Temporary(fitData))
					fitData=fitData*10000./Sxpar(fit_header,'CALIBRAT')
				ENDIF
				saveData = fitData
				fitData = BytScl(fitData)
				self.dim = Size(fitData , /Dimensions)

				IF Numbers GE self.numbers THEN BEGIN
					status = Dialog_Message('not enough memory', Title = 'warn')
				ENDIF ELSE BEGIN
					data = BytArr(Numbers,self.dim[0],self.dim[1])
					data[0,*,*] = Temporary(fitData)
				ENDELSE
				t = 0
				IF numbers LT 35 THEN proValue = Fix(35/Double(numbers))
				IF numbers GT 35 THEN proValue = 35/Double(numbers)
				oSystem.oProcess->mapBase , 1
				FOR i = 1 , Numbers-1 DO BEGIN
					IF round(self.Process+proValue) LT 32 THEN BEGIN
						FOR j = self.Process , round(self.Process+proValue) DO BEGIN
							oSystem.oProcess->DoProcess , j
						ENDFOR
						self.Process = round(self.Process+proValue)
					ENDIF
					fitData = ReadFitData(filename[i],fit_header)
					seg= Strmid(File_BaseName(filename[i]), 0, 1)
					number = ['L','Q','U']
					temp = Where(seg EQ number , count)
					IF count NE 0 THEN BEGIN
						fitData = Swap_Endian(Temporary(fitData))
						fitData=fitData*10000./Sxpar(fit_header,'CALIBRAT')
					ENDIF
					newData = Temporary(fitData)
;					self->acpoleImage , saveData , fitData , newData
					newData =BytScl(newData)
					dim = Size(Reform(newData) , /Dimensions)
					IF dim[0] EQ self.dim[0] AND dim[1] EQ self.dim[1] THEN BEGIN
						data[i,*,*] = Temporary(Reform(newData))
						t = [t,i]
					ENDIF
				ENDFOR
				oSystem.oProcess->DoProcess , 35
				Ptr_Free,self.Data
				Ptr_Free,self.dataFile
				self.fileNumber = N_Elements(t)
				fileName = File_BaseName(fileName[t])
				self.dataFile = Ptr_New(fileName)
				self.Data = Ptr_New(Temporary(data[t,*,*]))
				Widget_Control,self.list,Set_Value = *(self.dataFile)
				self.type = 1
				data = 0
			ENDIF
		ENDIF ELSE BEGIN
			status = Dialog_Message('please select more files', Title = 'warn')
		ENDELSE
		self->CreateView
		oSystem.oProcess->mapBase , 0
	ENDIF
END
;+
;Create view
;+
PRO sesCartoon::CreateView
	COMPILE_OPT IDL2
	oSystem = self.oSystem
	cartoon = (oSystem.mainDraw).cartoonBase
	image = (oSystem.mainDraw).frontBase
	IF Obj_Valid(oSystem.CurrentPro) THEN BEGIN
		oImage = (oSystem.CurrentPro).oImage
		oImage->SetProperty,Hide = 1
	ENDIF
	Widget_Control, self.PlayDraw, Get_Value = oWindow
	self.oWindow =oWindow
	self.oWindow->SetProperty, Graphics_Tree = oSystem.oScene
	self.oWindow->SetCurrentCursor, 'ARROW'
	self.oWindow->Draw, oSystem.oScene

	self.oView = Obj_New('IDLgrView'			, $
						  Color = [128,128,128]	, $
						  Eye = 101				, $
						  ZClip = [100,-100]		)

;	oSystem.oScene->Add , self.oView

	drawSize = [(oSystem.mainDraw).drawSize,self.dim[0], self.dim[1]]
	Type = 'initSize'

	sesViewSize, drawSize, Type = type				 	       , $
						 	ZoomRate = zoom			 	       , $
						 	windowVD = windowVD		           , $
							viewPlane = viewPlane	           , $
							viewDim = viewDim		           , $
							currentXY=currentXY                , $
							oDraw = self.PlayDraw			   , $
							oView = self.oView                 , $
							viewLoc = viewLoc

	IF KeyWord_Set(viewDim) THEN self.oView->SetProperty, Dimensions = viewDim
	IF KeyWord_Set(viewLoc) THEN self.oView->SetProperty, Location = viewLoc
	IF KeyWord_Set(windowVD) THEN BEGIN
		Widget_Control, self.PlayDraw,Draw_XSize = windowVD[0], Draw_YSize = windowVD[1]
	ENDIF
 	Widget_Control, self.PlayDraw, Scr_XSize = (oSystem.mainDraw).drawSize[0], $
 						           Scr_YSize = (oSystem.mainDraw).drawSize[1]

 	self.oView->SetProperty, ViewPlane_Rect = viewPlane

	self.oModel = Obj_New('IDLgrModel')
	self.oView->Add, self.oModel
	self.oWindow->SetProperty, Graphics_Tree=self.oView
	self.observer = Obj_New('sesCartoonTimer')
	self.playModel = Obj_New('IDLgrModel', Render_Method=1)
    self.observer->SetProperty, OIMAGES=self.playModel
    self.oWindow->AddWindowEventObserver, self.observer
	oImageColl = ObjArr(self.fileNumber)
	self.carContainer->Add,self.oView
	self.carContainer->Add,self.oModel
	self.carContainer->Add,self.playModel
	self.carContainer->Add,self.observer

	FOR i=0, self.fileNumber-1 DO BEGIN
        oImageColl[i] = Obj_New('IDLgrImage', (*(self.Data))[i,*,*], /Interp)
        self.playModel->Add, oImageColl[i]
        self.carContainer->Add,oImageColl[i]
    ENDFOR

    self.currentFrame = 0
    self.oModel->Add, self.playModel

    self.oWindow->SetTimerInterval, 0.1
    self.observer->SetProperty, INC=1

    Widget_Control, self.cBase, TIMER=1

	Widget_Control, cartoon, Map = 1
	Widget_Control, image, Map = 0
	self.oWindow -> Draw, self.oView

END
;+
;handle event
;+
PRO sesCartoon::HandleEvent, event
	COMPILE_OPT IDL2
	oSystem = self.oSystem
	UName = Widget_Info(event.id, /UName)
	tagName = Tag_Names(event, /Structure_Name)
	cartoon = (oSystem.mainDraw).cartoonBase
	image = (oSystem.mainDraw).frontBase
	IF Tag_Names(event, /Structure_Name) EQ 'WIDGET_KILL_REQUEST' THEN BEGIN
		Ptr_Free,self.Data
		Ptr_Free,self.dataFile
		Widget_Control, self.cBase, Timer=1
		Widget_Control, event.top, /Destroy
		Widget_Control, image, Map = 1
		Widget_Control, cartoon, Map = 0
		IF Obj_Valid(oSystem.CurrentPro) THEN BEGIN
			oImage = (oSystem.CurrentPro).oImage
			oImage->SetProperty,Hide = 0
		ENDIF
		Obj_Destroy, self.carContainer
        oSystem.oWindow -> Draw,oSystem.oScene
		Return
	ENDIF
	IF tagName EQ 'WIDGET_TRACKING' THEN BEGIN
		IF event.enter EQ 1 THEN BEGIN
			self->Adjust , type = 0 , UName = UName
		ENDIF ELSE BEGIN
			self->Adjust , type = 1 , UName = UName
		ENDELSE
	ENDIF
	IF tagName EQ 'WIDGET_DRAW' THEN BEGIN
		IF event.press EQ 1 THEN BEGIN
			self->Adjust , type = 2 , UName = UName
		ENDIF
		IF event.press EQ 0 THEN BEGIN
			self->Adjust , type = 3 , UName = UName
		ENDIF
	ENDIF
	IF UName EQ 'listRate' THEN BEGIN
		IF self.type EQ 1 THEN BEGIN
			interval = 1.0 / event.value
			self.CartoonRate = event.value
	        self.oWindow->SetTimerInterval, interval
	    ENDIF
	ENDIF
	IF UName EQ 'fileList' THEN BEGIN
		IF event.index NE self.recordIndex THEN BEGIN
	        self.observer->SetProperty, INC = event.index
	        self.observer->OnTimer, self.oWindow
	        self.observer->SetProperty, INC = event.index
	        self.recordIndex = event.index
        ENDIF

	ENDIF

END
;+
;create widget
;+
PRO sesCartoon::Create
	COMPILE_OPT IDL2
	oSystem = self.oSystem
	Device, Get_Screen_Size = screenSize
	xOff = 4
	yOff = screenSize[1]-(oSystem.baseSize)[1]-2

	self->ReadBmp

	self.carContainer = Obj_New('IDL_Container')

	cBase = Widget_Base(Group_Leader = self.mainBase		, $
		                UName      = 'oCartoon' 	        , $
		                UValue	   = self					, $
		                Title      = 'Cartoon'		        , $
		                Space      = 2          			, $
		                XOffSet    = xOff					, $
		                YOffSet    = yOff					, $
		                /Modal                              , $
		                /ToolBar 							, $
		                /Column		               			, $
		                /Floating               			, $
		                /Tlb_Kill_Request_Events 			)

	self.cBase = cBase

	openBase = Widget_Base(cBase          , $
						   /Row           , $
						   /Align_Left    , $
						   Space = 5        $
	                      )

	self.openBu = Widget_Draw(openBase				, $
							  Retain = 2			, $
							  UName = 'open'		, $
							  /Button_Events      	, $
							  /Tracking_Events    	, $
							  Scr_XSize = 20	    , $
							  Scr_YSize = 20		  )

;	self.deleBu = Widget_Draw(openBase				, $
;							  Retain = 2			, $
;							  UName = 'dele'		, $
;							  /Button_Events      	, $
;							  /Tracking_Events    	, $
;							  Scr_XSize = 20	    , $
;							  Scr_YSize = 20		  )

	self.saveBu = Widget_Draw(openBase				, $
							  Retain = 2			, $
							  UName = 'save'		, $
							  /Button_Events      	, $
							  /Tracking_Events    	, $
							  Scr_XSize = 20	    , $
							  Scr_YSize = 20		  )

	self.list = Widget_List(cBase                    , $
					   Value = ''               , $
					   YSize=25                 , $
					   XSize=24                 , $
					   UName='fileList'         )

	listBase = Widget_Base(cBase                , $
						   /Row                 , $
						   Space = 5              $
						  )

	self.listRate = Widget_Slider(listBase      , $
	                              Minimum=1     , $
	                              Maximum=200   , $
	                              XSize = 200    , $
                                  UName='listRate')

	controlBase = Widget_Base(cBase           , $
							   /Row           , $
							   Space = 5        $
							  )

	self.playBu = Widget_Draw(controlBase			, $
							  Retain = 2			, $
							  UName = 'play'		, $
							  /Button_Events      	, $
							  /Tracking_Events    	, $
							  Scr_XSize = 20	    , $
							  Scr_YSize = 20		  )

	self.backBu = Widget_Draw(controlBase			, $
							  Retain = 2			, $
							  UName = 'back'		, $
							  /Button_Events      	, $
							  /Tracking_Events    	, $
							  Scr_XSize = 20	    , $
							  Scr_YSize = 20		  )

	self.stopBu = Widget_Draw(controlBase			, $
							  Retain = 2			, $
							  UName = 'stop'		, $
							  /Button_Events      	, $
							  /Tracking_Events    	, $
							  Scr_XSize = 20	    , $
							  Scr_YSize = 20		  )

	self.headBu = Widget_Draw(controlBase			, $
							  Retain = 2			, $
							  UName = 'head'		, $
							  /Button_Events      	, $
							  /Tracking_Events    	, $
							  Scr_XSize = 20	    , $
							  Scr_YSize = 20		  )

	Widget_Control, cBase, /realize

	Widget_Control, self.openBu, Get_Value = drawOpen
;	Widget_Control, self.deleBu, Get_Value = drawDele
	Widget_Control, self.saveBu, Get_Value = drawSave
	Widget_Control, self.playBu, Get_Value = drawPlay
	Widget_Control, self.backBu, Get_Value = drawBack
	Widget_Control, self.stopBu, Get_Value = drawStop
	Widget_Control, self.headBu, Get_Value = drawHead

	self.drawOpen = drawOpen
;	self.drawDele = drawDele
	self.drawSave = drawSave
	self.drawPlay = drawPlay
	self.drawBack = drawBack
	self.drawStop = drawStop
	self.drawHead = drawHead
	draw = [drawOpen,drawPlay,drawBack,drawStop,drawHead,drawSave]

	FOR i = 0 , 5 DO BEGIN
		WSet, draw[i]
		TV, Reform(self.bmpArr[i*3,*,*,*], [3,20,20]), /True
	ENDFOR
	Widget_Control, self.listRate, Set_Value=10
	self.CartoonRate = 10

	XManager, 'SunEle'                              , $
	           cBase                                , $
	           /No_Block                            , $
	           Event_Handler = 'sesFrame_Event'     , $
  			   Cleanup = 'sesFrame_Cleanup'
END
;+
;clean up
;+
PRO sesCartoon::CleanUp
	COMPILE_OPT IDL2
	Obj_Destroy , self.carContainer
	Obj_Destroy , self.observer
	Ptr_Free,self.Data
	Ptr_Free,self.dataFile
END
;+
;initialize
;+
FUNCTION sesCartoon::Init  , oSystem = oSystem

	COMPILE_OPT IDL2
	self.oSystem = oSystem
	self.mainBase = oSystem.mBase
	self.RootDir = oSystem.RootDir
	self.foreColor = oSystem.foreColor
	self.signColor = oSystem.signColor
	self.baseSize =  (oSystem.mainDraw).drawSize
	self.numbers = 1000
	self.PlayDraw = (oSystem.mainDraw).drawCar
	self.Process = 1
	self->Create

	Return,1
END
;+
;Colorbar class name
;+
PRO sesCartoon__Define
	COMPILE_OPT IDL2
	void = { sesCartoon                                 , $
	         ;system parameter
	         mainBase           :    0L                 , $
			 baseSize           :    [0,0]              , $
			 RootDir            :    ''                 , $
			 cBase              :    0L                 , $
			 list               :    0L                 , $
			 listRate           :    0L                 , $
			 openBu             :    0L                 , $
;			 deleBu             :    0L                 , $
			 saveBu             :    0L                 , $
			 playBu             :    0L                 , $
			 backBu             :    0L                 , $
			 stopBu             :    0L                 , $
			 headBu             :    0L                 , $
			 drawOpen           :    0L                 , $
			 drawDele           :    0L                 , $
			 drawSave           :    0L                 , $
			 drawPlay           :    0L                 , $
			 drawBack           :    0L                 , $
			 drawStop           :    0L                 , $
			 drawHead           :    0L                 , $
			 PlayDraw           :    0L                 , $
			 bmpArr             :    BytArr(21,3,20,20)	, $
			 foreColor          :    IntArr(3)          , $
			 signColor          :    IntArr(3)          , $
			 oClick             :    IntArr(7)          , $
			 dim                :    [0,0]              , $
			 Data               :    Ptr_New()          , $
			 dataFile           :    Ptr_New()          , $
			 numbers            :    0                  , $
			 fileNumber         :    0                  , $
			 currentFrame       :    0                  , $
			 type               :    0                  , $
			 imageType          :    0                  , $
			 CartoonRate        :    0                  , $
			 Process            :    0                  , $
			 recordIndex        :    0                  , $

		    ;system objct
			 carContainer       :    Obj_New()          , $
			 observer           :    Obj_New()          , $
			 oWindow            :    Obj_New()          , $
			 oView              :    Obj_New()          , $
			 oModel             :    Obj_New()          , $
			 playModel          :    Obj_New()          , $
	         oSystem            :    Obj_New()            $

	        }
END