module JapiGraf

! Verse 2
! Zakladem je plocha PlotArea,podle ni se zvoli rozmer canvas a
! frame (resp.s menu)
! Vlastni graf se kresli do obdelniku - PlotArea - na canvas
!
!  ViewPort:
!      +-frame----------------------------------------------+
!      |          Hlavicka frame + menu                     |
!      |----------------------------------------------------|
!      | canvas             ^  PAtop                        |
!      |                    v                               |
!      |            +---------------------+                 |
!      | <--------->|  PlotArea           |<--------------->|
!      |   PAleft   |                     |     PAright     |
!      |            +---------------------+                 |
!      |                    ^  PAbottom                     |
!      |                    v                               |
!      +----------------------------------------------------+
!
! Normalni souradnice stinitka monitoru:
!   (0,0)+------------------------------------+
!        |                                    |
!        |                                    |
!        +------------------------------------+ (1,1)
!
!
 ! Uzivatelske souradnice (canvas,PlotArea)
!   	 +------------------------------------+ (uxmax,uymax)
!        |                                    |
!        |                                    |
!        +------------------------------------+ 
!    (uxmin,uymin)
!
!


use std_type
use japi
use rgbcolor

implicit none

private

intrinsic :: abs,int,min,max,modulo,trim,len_trim

PUBLIC ::	StartJapi,Nx2Pix,Ny2Pix,SetPAmargins,DefViewPort,&
			Real2Str,PlotSymbol3,PlotSymbol5,ShowVP,HideVP,&
			SetGcursor,USetGcursor,GetGcursor,SetFGcolor,SetBGcolor,&
			ClipCanvas,ClipPlotArea,OsaX,OsaY,PlotLabels,&
			Ubod2Pbod,Uline,ULineTo,DrawCircle, &
			SetCanvasFont, PlotFunction


public :: operator(+) , operator(-)

private :: PbodPlus, PbodMinus, UbodPlus, UbodMinus

! ------------ Uzivatelske TYPY ------------
! typ pro uzivatelske souradnice pro PlotArea
type,public :: userCO
	real(kind=DP) :: uxmin,uxmax,uymin,uymax
end type userCO

! typ pro informace o objektu (frame,canvas,PlotArea)
type,public :: objCO
	integer :: polx,poly,psirka,pvyska
end type objCO

! Informace o castech ViewPort
type,public :: UPinfo
	type(userCO) :: Uinfo
	type(objCO)	 :: Pinfo
end type UPinfo

! Inforamace o celem ViewPort
type,public :: ViewPortInfo
	integer :: frame, canvas
	type(UPinfo) :: canvasUPinfo, PlotAreaUPinfo
	TYPE(rgbcol) :: canvasRGBcolor, PlotAreaRGBcolor
	integer :: pix2ux, pix2uy
end type ViewPortInfo

! typ pro bod v uzivatelskych jednotkach
type,public :: Ubod
	real(kind=DP) :: x,y
end type Ubod
! typ pro bod v pixelech
type,public :: Pbod
	integer :: px,py
end type Pbod

! ============== interface pro operatory +, - ====================
interface operator(+)
	module procedure PbodPlus, UbodPlus
end interface
interface operator(-)
	module procedure PbodMinus, UbodMinus
end interface

! ----------------- typy pro kresbu symbolu ------------------
type,Public :: Symbol3
	integer(kind=i1b),dimension(9) :: pix
end type Symbol3

type,Public :: Symbol5
	integer(kind=i1b),dimension(25) :: pix
end type Symbol5



! ============== Nastavovane glob. promenne =============

! Zjistena sirka s vyska stinitka (pixelu) v StartJapi()
integer,public :: S_width, S_height 
! AspectRatio=S_width/Sheight, nastavi se v StartJapi
real(kind=DP),Public :: AspRatio

! Odsazeni leveho a spodniho okraje PlotArea od okraju canvas
! je mozne je v programu menit pred volanim DefViewPort
integer,public :: PAleft, PAbottom, PAtop ,PAright 
! Uschova, ve StartJapi se zkopiruji, nebo se nastavi SetPAmargin
INTEGER,parameter,private :: &
		sPAleft = 80, sPAbottom = 40, sPAtop = 30, sPAright=10

! Informace o castech ViewPort, prenesou se sem z DefViewPort
type(ViewPortInfo),private :: SVPinfo

! Graficky kursor
! nastaveni meni SetGcursor, Uline a ULineTo ho nastavi na koncovy bod
! v StartJapi se nastavi na Pbod(0,0)
type(Pbod),private :: Gcur

!Delka delicich carek
integer,public :: BigTick = 6 ,SmallTick = 2  ! velka a mala carka v pixelech


! Symboly v matici 3x3
type(Symbol3),parameter,public :: plus3 = Symbol3((/0,1,0,1,1,1,0,1,0/))
type(Symbol3),parameter,public :: krat3 = Symbol3((/1,0,1,0,1,0,1,0,1/))
type(Symbol3),parameter,public :: ctvr3 = Symbol3((/1,1,1,1,0,1,1,1,1/))
type(Symbol3),parameter,public :: diam3 = Symbol3((/0,1,0,1,0,1,0,1,0/))
type(Symbol3),parameter,public :: ctvr3f = Symbol3((/1,1,1,1,1,1,1,1,1/))
type(Symbol3),parameter,public :: diam3f = Symbol3((/0,1,0,1,1,1,0,1,0/))

! Symboly v matici 5x5
type(Symbol5),parameter,public :: plus5 = &
	Symbol5((/0,0,1,0,0,0,0,1,0,0,1,1,1,1,1,0,0,1,0,0,0,0,1,0,0/))
type(Symbol5),parameter,public :: krat5 = &
	Symbol5((/1,0,0,0,1,0,1,0,1,0,0,0,1,0,0,0,1,0,1,0,1,0,0,0,1/))
type(Symbol5),parameter,public :: ctvr5 = &
	Symbol5((/1,1,1,1,1,1,0,0,0,1,1,0,0,0,1,1,0,0,0,1,1,1,1,1,1/))
type(Symbol5),parameter,public :: diam5 = &
	Symbol5((/0,0,1,0,0,0,1,0,1,0,1,0,0,0,1,0,1,0,1,0,0,0,1,0,0/))
type(Symbol5),parameter,public :: ctvr5f = &
	Symbol5((/1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1/))
type(Symbol5),parameter,public :: diam5f = &
	Symbol5((/0,0,1,0,0,0,1,1,1,0,1,1,1,1,1,0,1,1,1,0,0,0,1,0,0/))
type(Symbol5),parameter,public :: kruh5 = &
	Symbol5((/0,1,1,1,0,1,0,0,0,1,1,0,0,0,1,1,0,0,0,1,0,1,1,1,0/))
type(Symbol5),parameter,public :: kruh5f = &
	Symbol5((/0,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,0/))
	
! ================== PROCEDURY ========================

contains

subroutine StartJapi()
	! Inicializace JAPI a zjisteni rozliseni obrazovky
	IF( .NOT. j_start()) THEN
		PRINT*, "can't connect to JAPI server"
  		CALL j_quit()
  		stop
	END IF
	call SetPAmargins()
	Gcur = Pbod(0,0)
	S_width = j_getscreenwidth()
	S_height = j_getscreenheight()
	AspRatio = real(S_height)/real(S_width)
end subroutine StartJapi

subroutine SetPAmargins()
	PAleft = sPAleft
	PAtop = sPAtop
	PAbottom = sPAbottom
	PAright = sPAright
end subroutine SetPAmargins

subroutine ShowVP(infVP)
	type(ViewPortInfo),intent(IN) :: infVP
	call j_show(infVP%frame)
end subroutine ShowVP

subroutine HideVP(infVP)
	type(ViewPortInfo),intent(IN) :: infVP
	call j_hide(infVP%frame)
end subroutine HideVP


! ------------------ Nastaveni rgb barev ----------------
subroutine SetFGcolor(infVP,barva)
	! Nastavi rgb_barvu popredi canvas
	type(ViewPortInfo),intent(in) :: infVP
	type(rgbcol),intent(in) :: barva
	call j_setcolor(infVP%canvas,barva%r,barva%g,barva%b)
end subroutine SetFGcolor

subroutine SetBGcolor(infVP,barva)
	! Nastavi rgb_barvu pozadi canvas
	type(ViewPortInfo),intent(in) :: infVP
	type(rgbcol),intent(in) :: barva
	call j_setcolorbg(infVP%canvas,barva%r,barva%g,barva%b)
end subroutine SetBGcolor

! ---------------------- Graficky kursor -------------------

subroutine SetGcursor(pxpy)
	! Nastavuje hodnotu Gcur
	type(Pbod),intent(IN) :: pxpy
	Gcur = pxpy
end subroutine SetGcursor

function GetGcursor() result(Gcursor)
	type(Pbod) :: Gcursor
	Gcursor = Gcur
end function GetGcursor

subroutine USetGcursor(infVP,Uxy,Poffxy)
	type(ViewPortInfo),intent(in) :: infVP
	type(Ubod),intent(in) :: Uxy
	type(Pbod),intent(in),optional :: Poffxy
	Gcur = Ubod2Pbod(infVP,Uxy)
	if (present(Poffxy)) Gcur = Gcur+Poffxy
end subroutine USetGcursor

! ------------- Normalni souradnice ----------------

function Nx2Pix(NormalniX) result(Pixelu)
	! Prevadi x-ovou normalni souradnici obrazovky na pixely
	real(kind=SP),intent(in) :: NormalniX
	Integer :: Pixelu
	Pixelu = int(NormalniX*S_width)
end function Nx2Pix

function Ny2Pix(NormalniY) result(Pixelu)
	! Prevadi y-ovou normalni souradnici obrazovky na pixely
	real(kind=SP),intent(in) :: NormalniY
	Integer :: Pixelu
	Pixelu = int(NormalniY*S_height)
end function Ny2Pix

! -------------nektere U-funkce a procedury -----------------

function Ubod2Pbod(infVP,xy) result(pxpy)
	! Prevod uzivatelskeho bodu na Pbod podle usrCA pro dany obj(=canvas)
	type(ViewPortInfo),intent(in) :: infVP
	type(Ubod),intent(in) :: xy
	type(Pbod) :: pxpy
	
	type(UPinfo) :: infCA
	integer :: objw, objh
	
	infCA = infVP%canvasUPinfo
	objw = infCA%Pinfo%psirka
	objh = infCA%Pinfo%pvyska
	pxpy%px = objw*&
		((xy%x-infCA%Uinfo%uxmin)/(infCA%Uinfo%uxmax-infCA%Uinfo%uxmin))
	pxpy%py = objh*&
		(1-((xy%y-infCA%Uinfo%uymin)/(infCA%Uinfo%uymax-infCA%Uinfo%uymin)))
end function Ubod2Pbod



subroutine ULine(infVP,xy1,xy2,barva)
	! Nakresli primku od Ubod1 do Ubod2 v rgb_barve
	!integer,intent(in) :: obj
	type(ViewPortInfo),intent(in) :: infVP
	type(Ubod),intent(in) :: xy1, xy2
	type(rgbcol),intent(in) :: barva
	type(Pbod) :: pxpy1, pxpy2
	type(UPinfo) :: infCA
	
	infCA = infVP%canvasUPinfo
	pxpy1 = Ubod2Pbod(infVP,xy1)
	pxpy2 = Ubod2Pbod(infVP,xy2)
	call SetFGcolor(infVP,barva)
	call j_drawline(infVP%canvas,pxpy1%px,pxpy1%py,pxpy2%px,pxpy2%py)
	Gcur = pxpy2
end subroutine ULine

Subroutine ULineTo(infVP,xy2,barva)
	! nakresli caru z pozice dane Gcur do xy2 a nastavi
	! Gcur na novou hodnotu
	!integer,intent(in) :: obj
	type(ViewPortInfo),intent(in) :: infVP
	type(Ubod),intent(in) ::xy2
	type(rgbcol),intent(in) :: barva
	type(Pbod) :: pxpy2
	
	type(UPinfo) :: infCA
	
	infCA = infVP%canvasUPinfo
	pxpy2 = Ubod2Pbod(infVP,xy2)
	call SetFGcolor(infVP,barva)
	call j_drawline(infVP%canvas,Gcur%px,Gcur%py,pxpy2%px,pxpy2%py)
	Gcur = pxpy2
end subroutine ULineTo


subroutine DrawCircle(infVP,stred,rx,barva)
	type(ViewPortInfo),intent(in) :: infVP
	type(Ubod),intent(in) :: stred
	real(kind=DP),intent(in) :: rx
	type(rgbcol),intent(in) :: barva
	type(Pbod) :: Pstred

	
	call SetFGcolor(infVP,barva)
	Pstred = Ubod2Pbod(infVP,stred)
	call j_drawoval(infVP%canvas,Pstred%px,Pstred%py,&
					int(rx*infVP%pix2ux),int(rx*infVP%pix2uy))
					
end subroutine DrawCircle
	
! ---------------- DefViewPort ----------------------------

subroutine DefViewPort(NposxFR,NposyFR,nadpisFR,&
						NsirkaPA,NvyskaPA,SetAspRatio,&
						UxMin,UxMax,UyMin,UyMax,&
					    canvasCol,PlotAreaCol,&
						VPinfo)
	! Definuje ViewPort tvoreny frame a v nem canvas
	! Nsirka,Nvyska = sirka a vyska PlotArea v normalnich souradnicich
	! NposX, NposY = poloha leveho horniho rohu frame v norm. souradnicich
	! nadpis = text v zahlavi frame
	! canvasCol,PlotAreaCol = barvy pozadi canvas a PlotArea v rgb_barve
	! UxMin,UxMax,UyMin,UyMax = uzivatelske meze pro PlotArea (do UserPA)
	! odpovidajici uzivatelske meze pro canvas se ulozi do UserCA
	! frame, canvas = vracene handlery na frame a canvas
	real(kind=SP),Intent(in) :: NposxFR,NposyFR,NsirkaPA,NvyskaPA
	character(len=*),intent(in) :: nadpisFR
	logical,intent(in) :: SetAspRatio
	type(rgbcol),intent(IN) :: canvasCol,PlotAreaCol
	real(kind=DP),intent(in) :: UxMin, UxMax, UyMin, UyMax
	type(ViewPortInfo),intent(out) :: VPinfo
	
	! Pro vypoctene rozmery canvas + frame a polohu frame
	integer :: frame,canvas
	type(UPinfo) :: infoCA , infoPA
	integer :: sirkaCanvas, vyskaCanvas 
	integer,parameter :: proFRx=25, proFRy=50
	! pocet pixelu na uzivatelskou jednotku
	integer :: sirkaPA,vyskaPA
	real(kind=DP) :: usrx2pix,usry2pix
	REAL(kind=SP) :: oprNsirkaPA
	
	oprNsirkaPA = NsirkaPA
	if (SetAspRatio) oprNsirkaPA = NvyskaPA*AspRatio
	sirkaPA = Nx2Pix(oprNsirkaPA)+1
	vyskaPA = Ny2Pix(NvyskaPA)+1
	sirkaCanvas = sirkaPA+PAleft+PAright
	vyskaCanvas = vyskaPA+PAtop+PAbottom
	
	! --- FRAME	---
	frame = j_frame(nadpisFR)
	call j_setpos(frame,Nx2Pix(NposxFR),Ny2Pix(NposyFR))
	call j_setsize(frame,sirkaCanvas+proFRx,vyskaCanvas+proFRy)
	call j_setnamedcolorbg(frame,J_WHITE)
	
	! --- CANVAS ---
	canvas = j_canvas(frame,sirkaCanvas,vyskaCanvas)
	call j_setcolorbg(canvas,canvasCol%r,canvasCol%g,canvasCol%b)
	call j_setpos(canvas,5,PAtop)
	call j_setflowlayout(frame,J_VERTICAL)
	
	! naplneni CA - hodnoty pro canvas
	usrx2pix = (Uxmax-Uxmin)/sirkaPA
	usry2pix = (Uymax-Uymin)/vyskaPA
	infoCA%Uinfo = userCO(UxMin-usrx2pix*PAleft,UxMax+usrx2pix*PAright,&
							UyMin-usry2pix*PAbottom,UyMax+usry2pix*PAtop)
	infoCA%Pinfo = objCO(0,0,sirkaCanvas,vyskaCanvas)
		
	! naplneni userPA hodnoty pro PlotArea
	infoPA%Uinfo = userCO(UxMin,UxMax,Uymin,UyMax)
	infoPA%Pinfo = objCO(PAleft,PAtop,sirkaPA,vyskaPA)
	
	! vybarveni PA	
	call j_setcolor(canvas,PlotAreaCol%r,PlotAreaCol%g,PlotAreaCol%b)
	call j_fillrect(canvas,PAleft,PAtop,sirkaPA,vyskaPA)
	
	! Clipping na celou canvas
	call j_cliprect(canvas,0,0,sirkaCanvas,vyskaCanvas)
	
	!ulozi do globalnich privatnich promennych
	VPinfo%PlotAreaUPInfo = infoPA
	VPinfo%CanvasUPInfo = infoCA
	VPinfo%frame = frame
	VPinfo%canvas = canvas
	VPinfo%canvasRGBcolor = canvasCol
	VPinfo%PlotAreaRGBcolor = PlotAreaCol
	VPinfo%pix2ux = sirkaPA/abs(UxMax-UxMin) 
	VPinfo%pix2uy = vyskaPA/abs(UyMax-UyMin)
	SVPinfo = VPinfo
	
end subroutine DefViewPort

! ------------------- Clipping ------------------------
subroutine ClipCanvas(infVP)
	type(ViewPortInfo),intent(in) :: infVP
	type(UPinfo) :: infCA
	infCA = infVP%canvasUPinfo
	call j_cliprect(infVP%canvas,infCA%Pinfo%polx,infCA%Pinfo%poly,&
					infCA%Pinfo%psirka,infCA%Pinfo%pvyska)
end subroutine ClipCanvas 
	
subroutine ClipPlotArea(infVP)
	type(ViewPortInfo),intent(in) :: infVP
	type(UPinfo) :: infPA
	infPA = infVP%PlotAreaUPinfo
	call j_cliprect(infVP%canvas,infPA%Pinfo%polx,infPA%Pinfo%poly,&
					infPA%Pinfo%psirka,infPA%Pinfo%pvyska)
end subroutine ClipPlotArea 

! -------------- Osy -------------------

subroutine OsaX(infVP,UodX,UdoX,UpolY,Uvkrok,Mdilku,barva,gridX,gridCol)
	type(ViewPortInfo),intent(in) :: infVP 
	real(kind=DP),intent(in) :: UpolY,UodX,UdoX,Uvkrok
	integer,intent(in) :: Mdilku
	type(rgbcol),intent(in) :: barva, gridCol
	logical,intent(in) :: gridX
	
	type(UPinfo) :: infPA
	real(kind=DP) :: odX,doX,polY,yPAmin,yPAmax,UMkrok
	real(kind=DP) :: Ux1vd,zbytek,Ux
	type(Pbod) ::  Pxy
	integer :: i,delka,offX,offY
	character(len=20) :: popis
	
	
	infPA = infVP%PlotAreaUPinfo
	
	! Pripadna korekce nastavenych hodnot osa jen do PA
	OdX = max(UodX,infPA%Uinfo%uxmin)
	DoX = min(UdoX,infPA%Uinfo%uxmax)
	yPAmin = infPA%Uinfo%uymin
	yPAmax = infPA%Uinfo%uymax
	polY = min(max(yPAmin,UpolY),yPAmax)
	UMkrok = UVkrok/Mdilku 
	! Deleni a popis osy
	! najit polohu 1.velke delici carky Ux
	zbytek = modulo(OdX,Uvkrok)
	Ux1vd = OdX - zbytek
	IF (zbytek>0.0_DP) Ux1vd = Ux1vd + Uvkrok
	! Kresba deleni a popis
	Ux = Ux1vd
	Do
		call SetFGcolor(infVP,barva)
		Pxy = Ubod2Pbod(infVP,Ubod(Ux,poly))
		call j_drawline(infVP%canvas,Pxy%px,Pxy%py,Pxy%px,Pxy%py+BigTick)
		! Popis hlavniho deleni
		call Real2Str(Ux,popis,delka)
		offY = j_getfontascent(infVP%canvas)
		offX = (j_getfontheight(infVP%canvas)*0.6*delka)/2
		call j_drawstring(infVP%canvas,Pxy%px-offX,Pxy%py+BigTick+offY+2,popis) 
		if (Ux==DoX) Exit ! Velkou carku ano, male a grid uz ne
		do i=1,Mdilku-1
			Pxy = Ubod2Pbod(infVP,Ubod(Ux+i*UMkrok,poly))
			call j_drawline(infVP%canvas,Pxy%px,Pxy%py,Pxy%px,Pxy%py+SmallTick)
		end DO
		if (gridX .and. ((Ux>OdX) .or.(Ux<DoX))) &
			call Uline(infVP,Ubod(Ux,yPAmin),Ubod(Ux,yPAmax),gridCol)
		Ux = Ux+UVkrok
		if (Ux>DoX) exit
	end do
	! Kresba vlastni osy
	call Uline(infVP,Ubod(odX,polY),Ubod(doX,polY),barva)
end subroutine OsaX


subroutine OsaY(infVP,UodY,UdoY,UpolX,Uvkrok,Mdilku,barva,gridY,gridCol)
	type(ViewPortInfo),intent(in) :: infVP 
	real(kind=DP),intent(in) :: UpolX,UodY,UdoY,Uvkrok
	integer,intent(in) :: Mdilku
	type(rgbcol),intent(in) :: barva, gridCol
	logical,intent(in) :: gridY
	
	type(UPinfo) :: infPA
	real(kind=DP) :: odY,doY,polX,xPAmin,xPAmax,UMkrok
	real(kind=DP) :: Uy1vd,zbytek,Uy
	type(Pbod) ::  Pxy
	integer :: i,offX,offY,delka
	character(len=20) :: popis
	
	
	infPA = infVP%PlotAreaUPinfo
	
	! Pripadna korekce nastavenych hodnot osa jen do PA
	OdY = max(UodY,infPA%Uinfo%uymin)
	DoY = min(UdoY,infPA%Uinfo%uymax)
	xPAmin = infPA%Uinfo%uxmin
	xPAmax = infPA%Uinfo%uxmax
	polX = min(max(xPAmin,UpolX),xPAmax)
	UMkrok = UVkrok/Mdilku 
	
	! Deleni a popis osy
	! najit polohu 1.velke delici carky Ux
	zbytek = modulo(OdY,Uvkrok)
	Uy1vd = OdY - zbytek
	IF (zbytek>0.0_DP) Uy1vd = Uy1vd + Uvkrok
	! Kresba
	!call Uline(infVP,Ubod(polX,OdY),Ubod(polX,DoY),barva)
	Uy = Uy1vd
	Do
		call SetFGcolor(infVP,barva)
		Pxy = Ubod2Pbod(infVP,Ubod(polX,Uy))
		call j_drawline(infVP%canvas,Pxy%px,Pxy%py,Pxy%px-BigTick,Pxy%py)
		call Real2Str(Uy,popis,delka)
		offY = j_getfontascent(infVP%canvas)/2-1
		offX = offY*delka+BigTick+4
		call j_drawstring(infVP%canvas,Pxy%px-offX,Pxy%py+offY,trim(popis)) 
		if (Uy==DoY) EXIT !Velkou carku ano, male uz ne
		do i=1,Mdilku-1
			Pxy = Ubod2Pbod(infVP,Ubod(polX,Uy+i*UMkrok))
			call j_drawline(infVP%canvas,Pxy%px,Pxy%py,Pxy%px-SmallTick,Pxy%py)
		end DO
		if (gridY .and. ((Uy>OdY) .and.(Uy<DoY))) &
			call Uline(infVP,Ubod(xPAmin,Uy),Ubod(xPAmax,UY),gridCol)
		Uy = Uy+UVkrok
		if (Uy>DoY) exit
	end do
	call Uline(infVP,Ubod(polX,OdY),Ubod(polX,DoY),barva)
end subroutine OsaY

subroutine PlotLabels(infVP,xlabel,ylabel,nadpis,barva)
	type(ViewPortInfo),intent(in) :: infVP
	character(len=*),intent(in) :: xlabel,ylabel,nadpis
	type(rgbcol),intent(in) :: barva
	integer :: strlen,xpos,ypos,fontascent
	type(objCO) :: PAinf
	
	PAinf = infVP%PlotAreaUPInfo%Pinfo
	fontascent = j_getfontascent(infVP%canvas)
	call SetFGcolor(infVP,barva)
	! xlabel
	strlen = len(xlabel)
	xpos = PAinf%polx + (PAinf%psirka - strlen*0.5*fontascent)/2.0
	ypos = PAinf%poly+PAinf%pvyska+BigTick+2*fontascent+2
	call j_drawstring(infVP%canvas,xpos,ypos,xlabel)
	! y label
	strlen = len(ylabel)
	xpos = PAinf%polx - (strlen*0.85*fontascent)
	ypos = PAinf%poly+(PAinf%pvyska+j_getfontheight(infVP%canvas))/2.0
	call j_drawstring(infVP%canvas,xpos,ypos,ylabel)
	! nadpis
	strlen = len(nadpis)
	xpos = PAinf%polx + (PAinf%psirka - strlen*0.5*fontascent)/2.0
	ypos = PAinf%poly - 12
	call j_drawstring(infVP%canvas,xpos,ypos,nadpis)
	
end subroutine PlotLabels
	
	


! ----------------- FONTY ----------------------

subroutine SetCanvasFont(infVP,jmeno,styl,velikost,barva)
	type(ViewPortInfo),intent(in) :: infVP
	integer,intent(in) :: jmeno,styl,velikost
	type(rgbcol),intent(in) :: barva
	
	! jmeno : J_COURIER, J_HELVETIA, J_TIMES, J_DIALOGIN, J_DIALOGOUT
	! styl  : J_PLAIN, J_BOLD, J_ITALIC
	
	call SetFGcolor(infVP,barva)
	call j_setfont(infVP%canvas,jmeno,styl,velikost)
	
end subroutine SetCanvasFont




! ---------------- Pomocne procedury ---------------------

subroutine Real2Str(cislo,cstr,delka)
	! prevod realneho cisla na retezec max delky <znaku>
	real(kind=DP),intent(in) :: cislo
	character(len=20),intent(out) :: cstr
	integer,intent(out) :: delka
	real(kind=DP),parameter :: HrRad1 = 1.0e3_DP ,HrRad2 = 1.0e-3_DP
	character(len=10) :: mant,expo
	integer :: polE,pom
	
	if (cislo==0.0_DP) then
		cstr = "0"
		delka = 1
		return
	end if
	if (abs(cislo)<= HrRad1.and.abs(cislo)>=HrRad2) then
		write(unit=cstr,fmt="(f8.2)")cislo
	else
		write(unit=cstr,fmt="(ES15.2E3)")cislo
	end if
	cstr = adjustl(cstr) ! presune nevyznamne znaky pred cislem za cislo
	delka = len_trim(cstr)
	if (abs(cislo)<= HrRad1.and.abs(cislo)>=HrRad2) then	
		do
			if (index(cstr(:delka),"0",.true.) /= delka) exit
			delka = delka - 1
		end do
		if (index(cstr(:delka),".",.true.)== delka) delka = delka-1
		cstr = cstr(:delka)
	else                          ! cisla s exponentem
		polE = index(cstr,"E") ! poloha E 
		mant = cstr(:polE-1)
		expo = cstr(polE+1:)
		! uprava exponentu
		pom = index(expo,"0")
		if (pom>0) then
			do 
				pom = pom+1
				if (index(expo(pom:),"0") /= pom) exit
			end do
			expo = expo(pom+1:)
		end if
		! uprava mantisy
		pom = len_trim(mant)
		do
			if (index(mant(:pom),"0",.true.)/=pom) exit
			pom = pom-1
		end do
		if (index(mant(:pom),".",.true.)==pom) pom = pom-1
		if (cstr(polE+1:polE+1)=="-") expo = "-"//expo
		cstr = mant(:pom)//"e"//expo
	end if
end subroutine Real2Str

subroutine PlotSymbol3(infVP,Upoloha,symbol,barva)
	type(ViewPortInfo),intent(in) :: infVP
	type(Ubod),intent(in) :: Upoloha
	type(Symbol3),intent(in) :: symbol
	type(rgbcol),intent(in) :: barva
	
	type(Pbod) :: Pxy
	integer :: i,px,py
	
	call SetFGcolor(infVP,barva)
	Pxy = Ubod2Pbod(infVP,Upoloha)
	px = Pxy%px-1
	py = Pxy%py-1
	do i=1,9
		if (symbol%pix(i) == 1_i1b) call j_drawpixel(infVP%canvas,px,py)
		px = px+1
		if (i==3 .or. i==6) px = px-3
		if (i==3 .or. i==6) py = py+1
	end do
end subroutine PlotSymbol3
		
	
subroutine PlotSymbol5(infVP,Upoloha,symbol,barva)
	type(ViewPortInfo),intent(in) :: infVP
	type(Ubod),intent(in) :: Upoloha
	type(Symbol5),intent(in) :: symbol
	type(rgbcol),intent(in) :: barva
	
	type(Pbod) :: Pxy
	integer :: i,px,py
	
	call SetFGcolor(infVP,barva)
	Pxy = Ubod2Pbod(infVP,Upoloha)
	px = Pxy%px-2
	py = Pxy%py-2
	do i=1,25
		if (symbol%pix(i) == 1_i1b) call j_drawpixel(infVP%canvas,px,py)
		px = px+1
		if (i==5 .or. i==10 .or. i==15 .or. i==20 ) px = px-5
		if (i==5 .or. i==10 .or. i==15 .or. i==20) py = py+1
	end do
end subroutine PlotSymbol5

subroutine PlotFunction(infVP,funX,barva,OdX,DoX,krokX)
	type(ViewPortInfo),intent(in) :: infVP
	interface
		function funX(x) result(y)
			use std_type
			real(kind=DP),intent(in) :: x
			!real(kind=DP),dimension(:),intent(in),optional :: param
			real(kind=DP) :: y
		end function funX
	end interface
	type(rgbcol),intent(in) :: barva
	real(kind=DP),intent(in),optional :: OdX,DoX,krokX
	
	real(kind=DP) :: xmin,xmax,x,dx
	xmin = infVP%PlotAreaUPInfo%Uinfo%uxmin
	xmax = infVP%PlotAreaUPInfo%Uinfo%uxmax
	if (present(OdX)) xmin = min(max(xmin,OdX),xmax)
	if (present(DoX)) xmax = max(min(xmax,DoX),xmin)
	
	call USetGcursor(infVP,Ubod(xmin,funX(xmin)))
	if (present(krokX)) then
		dx = krokX
	else
		dx =(xmax-xmin)/infVP%pix2ux
	end if		
	x = xmin
	do
		x = x+dx
		if (x>xmax) exit
		call UlineTo(infVP,Ubod(x,funX(x)),barva)
	end do
end subroutine PlotFunction


! ========= Procedury pro operatory +,- pro Pbod a Ubod

function PbodPlus(Pbod1,Pbod2) result(Pbodsuma)
	type(Pbod),intent(in) :: Pbod1, Pbod2
	type(Pbod) :: Pbodsuma
	Pbodsuma%px = Pbod1%px + Pbod2%px
	Pbodsuma%py = Pbod1%py + Pbod2%py
end function PbodPlus

function PbodMinus(Pbod1,Pbod2) result(Pbodsuma)
	type(Pbod),intent(in) :: Pbod1, Pbod2
	type(Pbod) :: Pbodsuma
	Pbodsuma%px = Pbod1%px - Pbod2%px
	Pbodsuma%py = Pbod1%py - Pbod2%py
end function PbodMinus

function UbodPlus(Ubod1,Ubod2) result(Ubodsuma)
	type(Ubod),intent(in) :: Ubod1, Ubod2
	type(Ubod) :: Ubodsuma
	Ubodsuma%x = Ubod1%x + Ubod2%x
	Ubodsuma%y = Ubod1%y + Ubod2%y
end function UbodPlus

function UbodMinus(Ubod1,Ubod2) result(Ubodsuma)
	type(Ubod),intent(in) :: Ubod1, Ubod2
	type(Ubod) :: Ubodsuma
	Ubodsuma%x = Ubod1%x - Ubod2%x
	Ubodsuma%y = Ubod1%y - Ubod2%y
end function UbodMinus

end module JapiGraf

