PRO PQLPROFILE,DAT,XSCALE,length=length,vertical=vertical,average=average,$
        title=title,xtitle=xtitle,ytitle=ytitle,datatitle=datatitle,$
        subtitle=subtitle,$
        xformat=xformat,yformat=yformat,$
        x_size=x_size,y_size=y_size,$
        outside=outside,cursor=cursor,$
        event=ev,P_reg=P_reg,change=change,$
        GROUP=GROUP,reset=reset,kill=kill,active=active
  
  common PQLPROFILE,DZ,lastwhich,lastdata,textw
  
  On_Error,2
  IF !DEBUG ne 0 THEN On_Error,0
  
  IF Keyword_SET(reset) THEN BEGIN
      DZ = 0
      return
  EndIF
  
;
; Check if we have enough information
;
  
  sz = Size(DAT)
  Ndims = sz(0)
  IF (N_elements(DAT) le 1 or Ndims gt 2) and NOT Keyword_SET(change) THEN $
        message,'Data must be either 1D or 2D array'
  
  IF Ndims eq 1 THEN BEGIN
      IF N_elements(XSCALE) ne 0 and N_elements(XSCALE) ne sz(1) THEN $
          message,'XSCALE must have same number of elements as DATA'
  EndIF
  
  IF N_elements(ev) gt 0 THEN BEGIN
      P_reg = pfind(ev,found)
      IF NOT found THEN return
  END ELSE IF N_elements(P_reg) eq 1 THEN BEGIN
     prestore,P_reg
     IF since_version('5.3') then begin
    ev = {Widget_DRAW}
    ev.x = !P.clip(0)+1
    ev.y = !P.clip(0)+1
     END ELSE begin
    command = ' ev = {Widget_DRAW, ID:0L, TOP:0L, HANDLER:0L, TYPE:0, ' + $
              'X:fix(!P.clip(0)+1), Y:fix(!P.clip(0)+1), press:0b, release:0b'
    IF since_version('5') THEN command = command + ', clicks:0L}' ELSE $
         command = command + '}'
    test = execute(command)
     ENDELSE
  END ELSE message,'Need to have either event or Plot Region'
  
;
; We now have reasonable event coordinates, and we have the P_region
;
; Defaults
;  
  
  IF N_elements(length) eq 0 THEN length=20
  IF N_elements(vertical) eq 0 THEN vertical=0B
  IF N_elements(average) eq 0 THEN average=1
  IF N_elements(title) eq 0 THEN title=''
  IF N_elements(xtitle) eq 0 THEN xtitle=''
  IF N_elements(ytitle) eq 0 THEN ytitle=''
  IF N_elements(datatitle) eq 0 THEN datatitle=''
  IF N_elements(subtitle) eq 0 THEN subtitle=''
  IF N_elements(xformat) eq 0 THEN xformat=''
  IF N_elements(yformat) eq 0 THEN yformat=''
  
  IF N_elements(x_size) eq 0 THEN BEGIN
      IF N_elements(Y_size) eq 1 THEN x_size = 2*y_size $
      ELSE                x_size = 500
  EndIF
  
  IF N_elements(y_size) eq 0 THEN y_size = fix(x_size/sqrt(2))
  
  IF Ndims eq 1 THEN BEGIN
      IF N_elements(XSCALE) eq 0 THEN BEGIN
      span = pconvert(P_reg,sz(1),/pix,/to_dat)$
                -pconvert(P_reg,0,/pix,/to_dat)
      XSCALE = findgen(sz(1))/(sz(1)-1)*span $
            + pconvert(P_reg,0,/pix,/to_data)
      END
  END ELSE XSCALE=0
  
  IF N_elements(DAT) gt 0 THEN DATA = { X:XSCALE, D:DAT}
  
; If no Pqlprofile has been invoked before, we need to init common block DZ
; (and the structure type)
  
  IF DATATYPE(DZ) ne 'STC' THEN BEGIN
      info = {QLPINFO,$
          base     : 0L,    $ ; Top level base
          init_ev  : ev,    $ ; (dummy) initial event
          P_reg    : -1,    $ ; The source Plot Region
          mbase    : 0L,    $ ; Uvalue used to store data.
          ndims    : Ndims, $ ; Data dimensionality
          length   : length,    $
                  lenmax   : 0,     $
                  fit      : 0,     $ ; Fit switch
          average  : average,   $
          vertical : vertical,  $
          len_text : 0L,    $
          avg_txtID: 0L,    $
          x    : EV.X,  $ ; Center of source line/box
          y    : EV.Y,  $ ; Center of source line/box
          ac       : EV.X,  $ ;   Actual center
          Plotreg  : -1,    $ ;   Plot region for the profile
          title    : title, $
          xtitle   : xtitle,    $
          ytitle   : ytitle,    $
          dtitle   : datatitle, $
          subtitle : subtitle,  $
          xformat  : xformat,   $
          yformat  : yformat,   $
          polyx    : [0,0], $ ;
          polyy    : [0,0]  $
          }
      dz = [info]
      lastwhich = -1
  END
  
  
;
; Is there already a widget corresponding to the call?
;
  
  active = 0
  which = (where(dz(*).P_reg eq P_reg,count))(0)
  
;
; If so, just update it..
;
  
  IF count gt 0 THEN BEGIN
      IF Keyword_SET(kill) THEN BEGIN
      Widget_CONTROL,dz(which).base,/destroy
      return
      EndIF
      active = 1
      IF lastwhich ne which or Keyword_SET(change) THEN BEGIN
      IF N_elements(data) eq 1 THEN BEGIN
          lastwhich = which
          lastdata = data
      END ELSE BEGIN
          Widget_CONTROL,dz(which).mbase,Get_UVALUE=lastdata
          lastwhich = which
      END
      IF Keyword_SET(change) THEN BEGIN
          Widget_CONTROL,dz(which).mbase,Set_UVALUE=lastdata
          IF Keyword_SET(title) THEN dz(which).title=title
          IF Keyword_SET(xtitle) THEN dz(which).xtitle=xtitle
          IF Keyword_SET(ytitle) THEN dz(which).ytitle=ytitle
          IF Keyword_SET(datatitle) THEN dz(which).dtitle=datatitle
          IF Keyword_SET(subtitle) THEN dz(which).subtitle=subtitle
          IF Keyword_SET(xformat) THEN dz(which).xformat=xformat
          IF Keyword_SET(yformat) THEN dz(which).yformat=yformat
      END
      END
      pqlp_plot,ev,which,change=change
      return
  END
  
;
; If this was just notification of change - don't make new widget.
;  
  
  IF Keyword_SET(change) or Keyword_SET(kill) THEN return
  
;
; Else: Create new widget to show data..
;
  
  which = N_elements(dz)
  dz = [dz,{QLPINFO}]
  
  
;
; Determine where to place top level base....
;
  
  p = tlb_place(x_size+20,y_size+50,pwindow=P_reg)
  xpos = p(0)
  ypos = p(1)
  
;
; Creation of widget base/other widgets....
;
  
  PQLPROFILEbase = Widget_BASE(TITLE = "PQLPROFILE",/column,$
                GROUP_LEADER=ev.top,Uvalue=which,space=0,$
                xoffset=xpos,yoffset=ypos)
  
  qlp = PQLPROFILEBASE ;shorthand
  qcol = Widget_BASE(qlp,/column,/frame)
  
  cmouse_s = {CMOUSE_S, btext:'', mtext:'', uvalue:'', avail:0}
  
  menu=[{CMOUSE_S,"Zoom out", "Zoom out (display more pixels)","ZOUT",7+8},$
        {CMOUSE_S,"Recenter", "Recenter on a pixel","RECENTER",7},$
   {CMOUSE_S,"Zoom in", "Zoom in (display fewer pixels)","ZIN",7},$   ; Paal
            {CMOUSE_S,"Select line", "Select line","LINE",7+8} ]
  
  cmouse,qlp,qcol,menu
  
;  label1 = Widget_LABEL(qcol,value='Mouse button action:')
;  rowbase0 = Widget_BASE(qcol,/row)
;  label2 = Widget_LABEL(rowbase0,value='1: Recenter',/frame)
;  label2 = Widget_LABEL(rowbase0,value='2: No action',/frame)
;  label2 = Widget_LABEL(rowbase0,value='3: No action',/frame)
  
  rowbase = Widget_BASE(qlp,/row)
  
  b = Widget_BUTTON(rowbase,value='Done',Uvalue='DONE')
  
  XPdMenu,['"Plot" {','"Plot to file" PSFILE','"Print" PSPRINT','}'],rowbase
  inner = Widget_BASE(qlp)
  
  b = Widget_BUTTON(rowbase,value='Save',Uvalue='SAVE')
  b = Widget_BUTTON(rowbase,value='Help',Uvalue='HELP')
  
  
  
  dummy = {PSELECT_S, btext:'', mtext:'', uvalue:'', flags:0}
  menu=[{PSELECT_S, ' None', 'No line fit','NOFIT',0},$
        {PSELECT_S, ' Gaussian', 'Gaussian profile', 'IGAUSS',0}]
    
  dummy = cw_pselect(rowbase,'Line fit:',menu)
  
  
  
  
;  
;  XPdMenu,['"Line Fitting" {','"Gaussian Fit" GAUSS',$
;      '"Amoebe" AMOEBE','"Other" OTHER','}'],rowbase
;  
  plotwin = Widget_DRAW(inner,xsize=x_size,ysize=y_size,uvalue='DRAW',$
            /button_events,/motion_events)
  
;
; Length slider
; The appearance of slider widgets differs from 3.0 to 3.X
;
  sub_version = float(!version.release)
  IF sub_version gt 3.0 THEN slide_offs=40 $
  ELSE               slide_offs=0
  
  len_base = Widget_BASE(qlp,/frame)
  len_text_base = Widget_BASE(len_base,/row)
  dummy = Widget_LABEL(len_text_base,value='Length of profile: ')
  len_text_id = Widget_TEXT(len_text_base,value=trim(length),$
                xsize=12,ysize=1)
  dummy = Widget_LABEL(len_text_base,value=' pixels')
  lenmax = max(sz(1:sz(0)))
  length = (length>3)<lenmax
  dummy = Widget_SLIDER(len_base,min=3,max=lenmax,xsize=x_size,$
            yoffset=slide_offs,$
            uvalue='LENGTH',/suppress,/drag,value=length)
      textbase = WIDGET_BASE(qlp,/column)
      textw = WIDGET_TEXT(textbase,xsize = 80,ysize = 1,/frame)
  
  
;
; 2D DATA ONLY:
;
  IF Ndims eq 2 THEN BEGIN
      
;
; Orientation
;
      xmenu,['Horizontal','Vertical'],qlp,/exclusive,/row,$
              UVALUE=['HORIZONTAL','VERTICAL'], buttons=buttons
      Widget_CONTROL,buttons(0),/set_button
;
; AVERAGE slider (only for 2D data)
;
      avgmax = max(sz(1:2))
      npix_base = Widget_BASE(qlp,/frame)
      avg_txt_base = Widget_BASE(npix_base,/row)
      dummy = Widget_LABEL(avg_txt_base,value='Average over ')
      avg_txtID = Widget_TEXT(avg_txt_base,value=trim(average),$
                xsize=5,ysize=1)
      dummy = Widget_LABEL(avg_txt_base,value=' pixels')
      dummy = Widget_SLIDER(npix_base,min=1,max=avgmax,xsize=x_size,$
                yoffset=slide_offs,$ $
                            uvalue='AVERAGE',/suppress,/drag,value=average)
      
  END ELSE avg_txtID = 0L
  
;
; That's the setup, now show ourselves...
;
  
  Widget_CONTROL, PQLPROFILEbase, /REALIZE
  
;
; And store vital information in the information block.
;  
  
  Widget_CONTROL,plotwin,Get_VALUE=qlpwnd
  SetWindow,qlpwnd
  Plotreg = pstore(1,0,0,/clean)
  
  dz(which).P_reg = P_reg
  dz(which).x = ev.x              ; Center of source box
  dz(which).y = ev.y
  dz(which).ndims = Ndims
  dz(which).length = length
  dz(which).lenmax = lenmax
  dz(which).vertical = vertical
  dz(which).average = average
  dz(which).title = title
  dz(which).xtitle= xtitle
  dz(which).ytitle= ytitle
  dz(which).dtitle=datatitle
  dz(which).xformat=xformat
  dz(which).yformat=yformat
  dz(which).plotreg = plotreg
  dz(which).base = PQLPROFILEbase
  dz(which).mbase=rowbase
  dz(which).len_text =len_text_id
  dz(which).avg_txtID=avg_txtID
  dz(which).polyx(*)=-1
  
  Widget_CONTROL,dz(which).mbase,Set_UVALUE=DATA
  lastdata = DATA
  lastwhich = which
  
;
; Sign up
;
  
  Xmanager, "PQLPROFILE", PQLPROFILEbase, CLEANUP='pqlp_cleanup'
  
;
; Update display..
;
  
  pqlp_plot,ev,which
  
END