module plotmtv

  ! Interface to plotmtv

  implicit none
  integer, parameter, private :: r8 = selected_real_kind(12,100)
  character(*), parameter, private :: version = &
       & '$Id: plotmtv.f90,v 1.6 2003/12/16 15:51:05 pletzer Exp $'
  
  type plotmtv_obj
     integer :: plotid ! id number
     logical :: hold ! set this to true for multiplots
     logical :: save ! set this to true if file needs to be saved
     logical :: freshstart ! true if new file is to be created
     logical :: display ! true to dosplay plot
     character(80) :: toplabel, xlabel, ylabel, zlabel, linelabel
     integer :: linewidth ! 1-32
     integer :: markersize ! 1-30
     integer :: fontsize ! 1-30
  end type plotmtv_obj

contains

  subroutine plotmtv_init(this)  
    implicit none
    type(plotmtv_obj) :: this

    real harvest
    call random_number(harvest)
    this % plotid = int(100000000 * harvest)
    this % hold = .FALSE.
    this % save = .FALSE.
    this % freshstart = .TRUE.
    this % display = .TRUE.
    this % toplabel = " "
    this % xlabel = " "
    this % ylabel = " "
    this % zlabel = " "
    this % linelabel = " "
    this % linewidth = 1
    this % markersize = 1
    this % fontsize = 10
  end subroutine plotmtv_init

  subroutine plotmtv_free(this)    
    implicit none
    type(plotmtv_obj) :: this
    character(12) nid
    
    if(.not. this % save) then
       write(nid,'(i12)') this % plotid
       print *,'rm table'//trim(adjustl(nid))//'.mtv'
       call system('rm table'//trim(adjustl(nid))//'.mtv')
    endif
  end subroutine plotmtv_free

  subroutine plotmtv_plot(this, x, y, line, marker)
   
     ! Dump x and y into file tableN.mtv where N is the plotid. Fire
     ! plotmtv if display = true. Multiple line plots are obtained
     ! by calling plot in sequence and setting hold = true.

 
    implicit none
    type(plotmtv_obj) :: this
    real(r8), intent(in) :: x(:), y(:)
    character(*) :: line, marker
    character(40) :: filename
    character(10) :: nid 

    integer linecolor, linetype, markertype, markercolor, i
    
    call plotmtv_set_color(marker(1:1), markercolor) 
    call plotmtv_set_marker(marker(2:2), markertype)
    call plotmtv_set_color(line(1:1), linecolor) 
    call plotmtv_set_line(line(2:2), linetype) 

    write(nid, '(i10)') this % plotid
    filename = 'table'//trim(adjustl(nid))//'.mtv'
    if(this % freshstart) then
       open(this % plotid, file=trim(filename), form='formatted', status='unknown')
    else
       open(this % plotid, file=trim(filename), form='formatted', status='unknown', &
            & position='append')
    endif
    write(this % plotid, *) ' '
    if(.not. this % hold) write(this % plotid, '(a)') "$DATA=COLUMN"
    write(this % plotid, '(a,a,a)') '%toplabel = "', trim(this % toplabel),'"'
    write(this % plotid, '(a,a,a)') '%xlabel = "', trim(this % xlabel),'"'
    write(this % plotid, '(a,a,a)') '%ylabel = "', trim(this % ylabel),'"'
    write(this % plotid, '(a,a,a)') '%linelabel = "', trim(this % linelabel),'"'
    write(this % plotid, '(a,i10)') '%linetype = ', linetype
    write(this % plotid, '(a,i10)') '%linewidth = ', this % linewidth
    write(this % plotid, '(a,i10)') '%linecolor = ', linecolor
    write(this % plotid, '(a,i10)') '%markertype = ', markertype
    write(this % plotid, '(a,i10)') '%markercolor = ', markercolor
    write(this % plotid, '(a,i10)') '%markersize = ', this % markersize
    write(this % plotid, *) 'x y'
    do i = 1, size(x)
       write(this % plotid, '(e13.5,e13.5)' ) x(i), y(i)
    end do
    close(this % plotid)

    ! fire
    if(this % display) then
       call system('plotmtv -bg white -fg black -geom 360x320 '// &
            & trim(filename)//' > plotmtv.log ')
    end if

    this % freshstart = .FALSE.

  end subroutine plotmtv_plot

  subroutine plotmtv_test(this)
    implicit none
    type(plotmtv_obj) :: this
    
    integer, parameter :: n = 101
    real(r8), dimension(n) :: x, y1, y2, y3
    real(r8) :: twopi
    integer i
    
    twopi = 2*acos(-1._r8)
    x = twopi*(/ (real(i-1,r8)/real(n-1,r8), i = 1, n) /)
    y1 = sin(x)
    y2 = sin(2*x)
    y3 = cos(3*x)
    
    call plotmtv_init(this)
    this % hold = .TRUE.  ! multigraph
    this % display = .FALSE. ! don't show
    this % xlabel = 'angle [rad]'
    this % ylabel = 'y'
    this % toplabel = ' test '
    this % linelabel = 'sin(x)'
    call plotmtv_plot(this, x, y1, 'r|', 'bx')
    this % linelabel = 'sin(2*x)'
    call plotmtv_plot(this, x, y2, 'g:', 'k^')
    this % display = .TRUE.
    this % linelabel = 'cos(3*x)'
    call plotmtv_plot(this, x, y3, 'm!', 'so')    
    ! call plotmtv_free(this)

  end subroutine plotmtv_test

! static members...................................................................

  subroutine plotmtv_set_line(line, code)
    implicit none
    character, intent(in) :: line
    integer, intent(out) :: code

    select case(line)
    case(' ')
       code = 0
    case('|')
       code = 1
    case('l')
       code = 2
    case('!')
       code = 4
    case(':')
       code = 3
    case default
       code = 3
    end select

  end subroutine plotmtv_set_line

  subroutine plotmtv_set_color(color, code)
    implicit none
    character, intent(in) :: color
    integer, intent(out) :: code

    select case(color)
    case(' ')
       code = -1
    case('k')
       code = 0
    case('y')
       code = 1
    case('c')
       code = 2
    case('g')
       code = 3
    case('r')
       code = 4
    case('b')
       code = 5
    case('m')
       code = 7
    case('p')
       code = 8
    case('s')
       code = 9
    case('n')
       code = 10
    case default
       code = -2 
    end select

  end subroutine plotmtv_set_color

  subroutine plotmtv_set_marker(marker, code)
    implicit none
    character, intent(in) :: marker
    integer, intent(out) :: code

    select case(marker)
    case(' ')
       code = 0
    case('.')
       code = 1
    case('+')
       code = 2
    case('x')
       code = 3
    case('s')
       code = 4
    case('l')
       code = 6
    case('^')
       code = 8
    case('v')
       code = 10
    case('o')
       code = 13
    case default
       code = -2
    end select
    
  end subroutine plotmtv_set_marker

end module plotmtv
