;*************************************************************************
pro PARgrDog::keywords, _extra=_extra
compile_opt IDL2, obsolete, hidden
if n_elements(_extra) eq 0 then return
	old_tags = tag_names(*self.keywords)
	new_tags = tag_names(_extra)
	new_keywords = _extra
	for i = 0, n_elements(old_tags)-1 do begin
		if (max(strpos(new_tags, old_tags[i])) eq -1) then $ ; Tag is not already there
			new_keywords = create_struct(new_keywords, old_tags[i], (*self.keywords).(i))
	endfor
	*self.keywords = new_keywords
end
;*************************************************************************
pro PARgrDog::show, over=over, _extra=_extra
compile_opt IDL2, obsolete, hidden
	call_method, self.type, self, over=over
end
;*************************************************************************
function PARgrDog::show, name=name, over=over, _extra=_extra ; Returns 1 if Name is present, 0 otherwise.
compile_opt IDL2, obsolete, hidden
	if n_elements(name) ne 0 then $
	if self.name eq name then begin
		call_method, self.type, self, over=over, _extra=_extra
		return, 1
	endif else begin
		call_method, self.type, self, over=over
		return, 0
	endelse
end
;*************************************************************************
pro PARgrDog::xyouts, _extra=_extra
compile_opt IDL2, obsolete, hidden
	self -> keywords, _extra=_extra
	self.type = 'XYOUTS'
	xyouts, *self.datax, *self.datay, *self.dataz, _extra=*self.keywords
end
;*************************************************************************
pro PARgrDog::contour, over=over, _extra=_extra
compile_opt IDL2, obsolete, hidden
	self -> keywords, _extra=_extra
	self.type = 'CONTOUR'
	contour, *self.datax, over=over, _extra=*self.keywords
end
;*************************************************************************
pro PARgrDog::plot, over=over, _extra=_extra
compile_opt IDL2, obsolete, hidden
	self -> keywords, _extra=_extra
	self.type = 'PLOT'
	if keyword_set(over) then oplot, *self.datax, *self.datay, _extra=*self.keywords else $
		plot, *self.datax, *self.datay, _extra=*self.keywords
end
;*************************************************************************
function PARgrDog::init, x, y, z, type=type, name=name, _extra=_extra ; Direct Object Graphics
compile_opt IDL2, obsolete, hidden
	if n_elements(y) eq 0 then begin
		y = x
		x = lindgen(n_elements(y))
		z = 0.0
	endif else if n_elements(z) eq 0 then z = 0.0
	self.datax = ptr_new(x)
	self.datay = ptr_new(y)
	self.dataz = ptr_new(z)
	if n_elements(_extra) ne 0 then self.keywords = ptr_new(_extra) else $
		self.keywords = ptr_new({VOID : 'VOID'})
	if n_elements(name) ne 0 then self.name = name
	if keyword_set(type) then call_method, type, self
return, 1
end
;*************************************************************************
pro PARgrDog::cleanup
compile_opt IDL2, obsolete, hidden
;Release all pointers and object references that are present in PARgrDisplay object.
tags = n_tags({PARgrDog})
for i=0, tags-1 do begin
	if size(self.(i), /type) eq 10 then ptr_free, self.(i)
;	if size(self.(i), /type) eq 11 then obj_destroy, self.(i)
endfor
end
;*************************************************************************
pro PARgrDog__define ; Direct Object Graphics
compile_opt IDL2, obsolete, hidden
	result = {PARgrDog, type : '', $ ; TYPE can be PLOT, XYOUTS or CONTOUR
	datax : ptr_new(), datay : ptr_new(), dataz : ptr_new(), command : '', keywords : ptr_new(), $
	name : ''}
end
;*************************************************************************
pro dplot_event, event
compile_opt IDL2, obsolete, hidden
draw = widget_info(event.top, /child)
widget_control, draw, get_value=win_id
wset, win_id
widget_control, event.top, get_uvalue=trash
case tag_names(event, /STRUCTURE_NAME) of
	'WIDGET_BASE' : widget_control, widget_info(event.id, /child), draw_xsize=event.x, draw_ysize=event.y
	'WIDGET_KBRD_FOCUS' : single_set, 'DPLOT', trash
	else :
	endcase
all_atoms = trash -> get(/all)
for i = 0, n_elements(all_atoms)-1 do all_atoms[i] -> show, over=i ne 0
end
;*************************************************************************
pro dplot_cleanup, id
compile_opt IDL2, obsolete, hidden
	widget_control, id, get_uvalue=trash
	obj_destroy, trash
end
;*************************************************************************
pro dplot, x, y, z, over=over, draw, top_base, _extra=_extra
compile_opt IDL2, obsolete, hidden
if keyword_set(over) then begin ; It may be that a new graphics is being added, or an old one modified.
	trash = single_get('DPLOT')
	all_atoms = trash -> get(/all)
	for i = 0, n_elements(all_atoms)-1 do is_present = 0 > all_atoms[i] -> show(over=i ne 0, _extra=_extra)
	if is_present eq 0 then begin
		temp = obj_new('PARgrDOG', x, y, z, _extra=_extra)
		trash -> add, temp
	endif
endif else begin ; Create new window
	top_base = widget_base(/tlb_size_event, /kbrd_focus_event)
	draw = widget_draw(top_base, xsize=600, ysize=400, retain=2);, /button, /motion)
	trash = obj_new('IDL_container')
	widget_control, top_base, /realize, set_uvalue=trash
	widget_control, draw, get_value=win_id
	widget_control, top_base, tlb_set_title='IDL '+strcompress(win_id, /rem)
	single_set, 'DPLOT', trash
	xmanager, 'dplot', top_base, /no_block, cleanup='dplot_cleanup'
	temp = obj_new('PARgrDOG', x, y, z, _extra=_extra)
	trash -> add, temp
endelse
end
;*************************************************************************

