/* Transitional library to replace calls to pgplot by calls to plplot
   Heavily inspired by the Fortran-95 library PG2PLplot by AstroFloyd:
   https://github.com/AstroFloyd/PG2PLplot
*/

#ifdef HAS_PG2PLPLOT

#include <cpgplot.h>

#include <plplot/plplot.h>
#include <vector>
#include <string>
#include <iostream>
#include <math.h>
#include <limits.h>

#ifdef DPQT
#include "qtdpuser.h"
#include "events.h"
#endif /* DPQT */

#define WARN printf
#define mm_per_inch 25.4

bool plplot_initialized = false;
bool pgask = true, firstplot = true;
int npanels = 1, cur_panel = 0;

void pg_initplplot(void) {
	if (!plplot_initialized) {
		plinit();
		plbop();
		plcol0(15);
	}
	plplot_initialized = true;
}

void advancepanel(void) {
	if (cur_panel == 0) plclear();
	cur_panel++;
	if (cur_panel > npanels) {
		if (pgask) {
#ifdef DPQT
//            QMessageBox::information(NULL, "dpuser", "Press OK to continue");
            dpusermutex->lock();
            dpCommandQFitsView("message", "Press OK to continue", 0);
            // now wait until the dialog has been closed;
            dpusermutex->lock();
            dpusermutex->unlock();
#else
			std::string s;
			std::cout << " Type <RETURN> for next page: ";
			std::getline(std::cin, s);
#endif /* DPQT */
		}
		cur_panel = 1;
		plclear();
	}
}

void reset_cmap0() {
	PLINT r[16] = { 0x00, 0xff, 0xff, 0x00, 0x7f, 0xff, 0xf5, 0xbe, 0xa5, 0x00, 0x8a, 0x00, 0x40, 0xff, 0xfa, 0xff };
	PLINT g[16] = { 0x00, 0x00, 0xff, 0xff, 0xff, 0xc0, 0xde, 0xbe, 0x2a, 0x00, 0x2b, 0xff, 0xe1, 0x00, 0x80, 0xff };
	PLINT b[16] = { 0x00, 0x00, 0x00, 0x00, 0xd4, 0xcb, 0xb3, 0xbe, 0x2a, 0xff, 0xe2, 0xff, 0xd0, 0xff, 0x72, 0xff };
	plscmap0(r, g, b, 16);
}

std::vector<PLFLT> toPLFLT(int n, const float *data) {
	std::vector<PLFLT> rv(n);
	for (int i = 0; i < n; i++) rv[i] = data[i];
	return rv;
}

std::string pg2pltext(const char *text) {
	std::string rv(text);
	for (int i = 0; i < rv.size(); i++) {
		switch (text[i]) {
			case '\\': rv[i] = '#'; break; // Replace the PGPlot escape character \ with the PLplot escape character # '
			default: break;
		}
	}
	return rv;
}

struct save_data {
	PLINT font_family, font_style, font_weight;
	PLINT line_width, line_style, line_color;
};

PLINT cur_width = 1, cur_style = 1, cur_color = 1, cur_fillstyle = 1;
PLINT devid = 0;
PLFLT ch_fac = 0.35, cur_x = 0., cur_y = 0.;

std::vector<save_data> savedata;

int XPTS, YPTS;

#define XSPA             2. / ( XPTS - 1 )
#define YSPA             2. / ( YPTS - 1 )

// Transformation function

PLFLT tr[6] = { 0., 1., 0., 0., 0., 1. };
//{ XSPA, 0.0, -1.0, 0.0, YSPA, -1.0 };

static void
mypltr( PLFLT x, PLFLT y, PLFLT *tx, PLFLT *ty, void * PL_UNUSED( pltr_data )) {
//	PLFLT tr[6];
//	for (int i = 0; i < 6; i++) tr[i] = ((PLFLT *)vtr)[i];
	*tx = tr[0] * x + tr[1] * y + tr[2];
	*ty = tr[3] * x + tr[4] * y + tr[5];
}

void cpgarro(float x1, float y1, float x2, float y2) { // TODO: use of plvect routine? This one does not draw arrow head
	PLFLT x[2] = { x1, x2 },
	      y[2] = { y1, y2 };
  
	plline(2, x, y);
//	plpoin(x[1], y[1], 2);
}
void cpgask(Logical flag) { WARN("WARNING: PGPLOT routine not implemented: pgask\n"); }
void cpgaxis(const char *opt, float x1, float y1, float x2, float y2, float v1, float v2, float step, int nsub, float dmajl, float dmajr, float fmin, float disp, float orient) { WARN("WARNING: PGPLOT routine not implemented: pgaxis\n"); }
int cpgband(int mode, int posn, float xref, float yref, float *x, float *y, char *ch_scalar) { WARN("WARNING: PGPLOT routine not implemented: pgband\n"); }
void cpgworld(float *xorg, float *xscl, float *yorg, float *yscl) { WARN("WARNING: PGPLOT routine not implemented: pgworld\n"); }
void cpgbbuf(void) { pg_initplplot(); }
int cpgbeg(int unit, const char *file, int nxsub, int nysub) {
#ifdef DPQT
        dpCommandQFitsView("plplot", "show", unit);
        plssub(nxsub, nysub);
        plclear();
        dpCommandQFitsView("plplot", "replot", unit);
#endif /* DPQT */
    if (!plplot_initialized) {
//		plinit();
#ifndef DPQT
		plsetopt("geometry", "800x600");
		plstart(file, nxsub, nysub);
#endif /* !DPQT */
//		plfontld(1);
		plspause(0);
		plplot_initialized = true;
	}
/*	plfontld(1);
	plssub(1, 1);
	plplot_initialized = false;
	plspause(0);
	pg_initplplot();
*/

//	plstart(file, nxsub, nysub);
//	plssub(1, 1);
	reset_cmap0();
	cpgslw(1);
	cpgsci(1);
	cpgsls(1);
	npanels = nxsub * nysub;
	cur_panel = 0;
	plclear();
	cur_width = cur_style = cur_color = cur_fillstyle = 1;

	return 1;
}
void cpgbin(int nbin, const float *x, const float *data, Logical center) { WARN("WARNING: PGPLOT routine not implemented: pgbin\n"); }
void cpgbox(const char *xopt, float xtick, int nxsub, const char *yopt, float ytick, int nysub) { plbox(xopt, xtick, nxsub, yopt, ytick, nysub); }
void cpgcirc(float xcent, float ycent, float radius) { plarc(xcent, ycent, radius, radius, 0., 360., 0., cur_fillstyle != 2); }
void cpgclos(void) { WARN("WARNING: PGPLOT routine not implemented: pgclos\n"); }
void cpgconb(const float *a, int idim, int jdim, int i1, int i2, int j1, int j2, const float *c, int nc, const float *tr, float blank) { WARN("WARNING: PGPLOT routine not implemented: pgconb\n"); }
void cpgconf(const float *a, int idim, int jdim, int i1, int i2, int j1, int j2, float c1, float c2, const float *tr) { WARN("WARNING: PGPLOT routine not implemented: pgconf\n"); }
void cpgconl(const float *a, int idim, int jdim, int i1, int i2, int j1, int j2, float c, const float *tr, const char *label, int intval, int minint) { WARN("WARNING: PGPLOT routine not implemented: pgconl\n"); }
void cpgcons(const float *a, int idim, int jdim, int i1, int i2, int j1, int j2, const float *c, int nc, const float *tr) { WARN("WARNING: PGPLOT routine not implemented: pgcons\n"); }
void cpgcont(const float *a, int idim, int jdim, int i1, int i2, int j1, int j2, const float *c, int nc, const float *tr) {
	PLFLT **data;
    plAlloc2dGrid(&data, idim, jdim);
	int z = 0;
	XPTS = idim;
	YPTS = jdim;
    for (int y = 0; y < jdim; y++) {
        for (int x = 0; x < idim; x++) {
			data[x][y] = a[z];
			z++;
		}
	}
	plcont(data, idim, jdim, i1, i2, j1, j2, toPLFLT(labs(nc), c).data(), labs(nc), pltr0, NULL);
	plFree2dGrid(data, idim, jdim);
}
void cpgctab(const float *l, const float *r, const float *g, const float *b, int nc, float contra, float bright) { WARN("WARNING: PGPLOT routine not implemented: pgctab\n"); }
int cpgcurs(float *x, float *y, char *ch_scalar) { WARN("WARNING: PGPLOT routine not implemented: pgcurs\n"); }
void cpgdraw(float x, float y) { pljoin(cur_x, cur_y, x, y); cpgmove(x, y); }
void cpgebuf(void) { WARN("WARNING: PGPLOT routine not implemented: pgebuf\n"); }
void cpgend(void) {
#ifdef DPQT
    dpCommandQFitsView("plplot", "update", 0);
#else
    WARN("WARNING: PGPLOT routine not implemented: pgend\n");/* plspause(0); plend(); plplot_initialized = false; */
#endif
}
void cpgenv(float xmin, float xmax, float ymin, float ymax, int just, int axis) {
	advancepanel();
	plenv(xmin, xmax, ymin, ymax, just, axis);
}
void cpgeras(void) { plclear(); }
void cpgerr1(int dir, float x, float y, float e, float t) {
	PLFLT x1, y1, x2, y2, xx = x, yy = y;
	switch (dir) {
		case 5: x1=x-e; x2=x+e; plerrx(1, &x1, &x2, &yy); break;
		case 6: y1=y-e; y2=y+e; plerry(1, &xx, &y1, &y2); break;
		default: break;
	}
}
void cpgerrb(int dir, int n, const float *x, const float *y, const float *e, float t) { WARN("WARNING: PGPLOT routine not implemented: pgerrb\n"); }
void cpgerrx(int n, const float *x1, const float *x2, const float *y, float t) { plerrx(n, toPLFLT(n, x1).data(), toPLFLT(n, x2).data(), toPLFLT(n, y).data()); }
void cpgerry(int n, const float *x, const float *y1, const float *y2, float t) { plerry(n, toPLFLT(n, x).data(), toPLFLT(n, y1).data(), toPLFLT(n, y2).data()); }
void cpgetxt(void) { WARN("WARNING: PGPLOT routine not implemented: pgetxt\n"); }
void cpggray(const float *a, int idim, int jdim, int i1, int i2, int j1, int j2, float fg, float bg, const float *tr) {
	PLFLT **data;
	plAlloc2dGrid(&data, idim, jdim);
	int z = 0;
	XPTS = idim;
	YPTS = jdim;
    for (int y = 0; y < jdim; y++) {
        for (int x = 0; x < idim; x++) {
			data[x][y] = a[z];
			z++;
		}
	}
	PLFLT i[2], r[2], g[2], b[2];

	i[0] = 0.0;         // left boundary
	i[1] = 1.0;         // right boundary

	r[0] = 0.0;     // hue -- low: red (arbitrary if s=0)
	r[1] = 1.0;     // hue -- high: red (arbitrary if s=0)

	g[0] = 0.0;     // lightness -- low: half-dark
	g[1] = 1.0;     // lightness -- high: light

	b[0] = 0.0;     // minimum saturation
	b[1] = 1.0;     // minimum saturation

	plscmap1n( 256 );
	c_plscmap1l(1, 2, i, r, g, b, NULL );
	
    plimagefr(data, idim, jdim, i1-.5, i2+.5, j1-.5, j2+.5, bg, fg, bg, fg, NULL, NULL);
//    plimage(data, idim, jdim, i1, i2, j1, j2, bg, fg, i1, i2, j1, j2);
	plFree2dGrid(data, idim, jdim);
}
void cpghi2d(const float *data, int nxv, int nyv, int ix1, int ix2, int iy1, int iy2, const float *x, int ioff, float bias, Logical center, float *ylims) { WARN("WARNING: PGPLOT routine not implemented: pghi2d\n"); }
void cpghist(int n, const float *data, float datmin, float datmax, int nbin, int pgflag) {
    plhist(n, toPLFLT(n, data).data(), datmin, datmax, nbin, pgflag);
//	if (pgflag == 0 || pgflag == 4) cpgenv(datmin, datmax, 0, 10, 0, 0);
//	WARN("WARNING: PGPLOT routine not implemented: pghist\n");
}
void cpgiden(void) { WARN("WARNING: PGPLOT routine not implemented: pgiden\n"); }
void cpgimag(const float *a, int idim, int jdim, int i1, int i2, int j1, int j2, float a1, float a2, const float *tr) { WARN("WARNING: PGPLOT routine not implemented: pgimag\n"); }
void cpglab(const char *xlbl, const char *ylbl, const char *toplbl) { pllab(pg2pltext(xlbl).c_str(), pg2pltext(ylbl).c_str(), pg2pltext(toplbl).c_str()); }
void cpglcur(int maxpt, int *npt, float *x, float *y) { WARN("WARNING: PGPLOT routine not implemented: pglcur\n"); }
void cpgldev(void) { WARN("WARNING: PGPLOT routine not implemented: pgldev\n"); }
void cpglen(int units, const char *string, float *xl, float *yl) { WARN("WARNING: PGPLOT routine not implemented: pglen\n"); }
void cpgline(int n, const float *xpts, const float *ypts) { plline(n, toPLFLT(n, xpts).data(), toPLFLT(n, ypts).data()); }
void cpgmove(float x, float y) { cur_x = x; cur_y = y; }
void cpgmtxt(const char *side, float disp, float coord, float fjust, const char *text) { plmtex(side, disp, coord, fjust, pg2pltext(text).c_str()); }
void cpgncur(int maxpt, int *npt, float *x, float *y, int symbol) { WARN("WARNING: PGPLOT routine not implemented: pgncur\n"); }
void cpgnumb(int mm, int pp, int form, char *string, int *string_length) { WARN("WARNING: PGPLOT routine not implemented: pgnumb\n"); }
void cpgolin(int maxpt, int *npt, float *x, float *y, int symbol) { WARN("WARNING: PGPLOT routine not implemented: pgolin\n"); }
int cpgopen(const char *device) { return cpgbeg(0, device, 1, 1); }
//	PLINT cur_stream = 0;
//	plmkstrm(&cur_stream);
//	plssub(1, 1);
//	plsdev(device);
//	plfontld(1);
//	plspause(0);
//	devid = cur_stream + 1;
//	plplot_initialized = false;
//	pg_initplplot();
//	return devid;
//}
void cpgpage(void) { pladv(0); plbop(); }
void cpgpanl(int nxc, int nyc) { WARN("WARNING: PGPLOT routine not implemented: pgpanl\n"); }
void cpgpap(float width, float aspect) { WARN("WARNING: PGPLOT routine not implemented: pgpap\n"); }
void cpgpixl(const int *ia, int idim, int jdim, int i1, int i2, int j1, int j2, float x1, float x2, float y1, float y2) { WARN("WARNING: PGPLOT routine not implemented: pgpixl\n"); }
void cpgpnts(int n, const float *x, const float *y, const int *symbol, int ns) { WARN("WARNING: PGPLOT routine not implemented: pgpnts\n"); }
void cpgpoly(int n, const float *xpts, const float *ypts) {
	std::vector<PLFLT>x, y;
	x = toPLFLT(n, xpts);
	y = toPLFLT(n, ypts);
	plfill(n, x.data(), y.data());
	if (cur_fillstyle == 2) {
		x.push_back(x[0]);
		y.push_back(y[0]);
		plline(n+1, x.data(), y.data());
	}
}
void cpgpt(int n, const float *xpts, const float *ypts, int symbol) { plpoin(n, toPLFLT(n, xpts).data(), toPLFLT(n, ypts).data(), symbol); }
void cpgpt1(float xpt, float ypt, int symbol) { float xpts[2], ypts[2]; xpts[0] = xpt; ypts[0] = ypt; cpgpt(1, xpts, ypts, symbol); }
void cpgptxt(float x, float y, float angle, float fjust, const char *text) {
	PLFLT d2r = atan(1.)/45.;
	PLFLT xmin, ymin, xmax, ymax;
	plgvpw(&xmin,&xmax,&ymin,&ymax);
// Convert angle -> dy/dx
	PLFLT dx = (xmax-xmin)*0.1, dy;

	if (fabs(angle) < 1.e-5) {                       // ang ~ 0 deg
		dy =  0.0;
	} else if (fabs(angle-90.) < 1.e-5 || fabs(90.-angle) < 1.e-5) {    // ang = +/-90deg
		dx =  0.0;
		dy = -1.0;                           // ang = -90deg
		if (fabs(angle-90.) < 1.e-5) dy = 1.;   // ang = +90deg
	} else {
		dx = 1.0;
		dy = dx*tan(angle*d2r) * (ymax-ymin)/(xmax-xmin);
		if ((angle > 90. && angle < 270.) || (angle < -90. && angle > -270.)) {
			dx = -dx;
			dy = -dy;
		}
	}
  
	plptex(x,y,dx,dy,fjust,pg2pltext(text).c_str());
}

void cpgqah(int *fs, float *angle, float *barb) { WARN("WARNING: PGPLOT routine not implemented: pgqah\n"); }
void cpgqcf(int *font) { WARN("WARNING: PGPLOT routine not implemented: pgqcf\n"); }
void cpgqch(float *size) { WARN("WARNING: PGPLOT routine not implemented: pgqch\n"); }
void cpgqci(int *ci) { WARN("WARNING: PGPLOT routine not implemented: pgqci\n"); }
void cpgqcir(int *icilo, int *icihi) { WARN("WARNING: PGPLOT routine not implemented: pgqcir\n"); }
void cpgqclp(int *state) { WARN("WARNING: PGPLOT routine not implemented: pgqclp\n"); }
void cpgqcol(int *ci1, int *ci2) { WARN("WARNING: PGPLOT routine not implemented: pgqcol\n"); }
void cpgqcr(int ci, float *cr, float *cg, float *cb) { WARN("WARNING: PGPLOT routine not implemented: pgqcr\n"); }
void cpgqcs(int units, float *xch, float *ych) { WARN("WARNING: PGPLOT routine not implemented: pgqcs\n"); }
void cpgqdt(int n, char *type, int *type_length, char *descr, int *descr_length, int *inter) { WARN("WARNING: PGPLOT routine not implemented: pgqdt\n"); }
void cpgqfs(int *fs) { WARN("WARNING: PGPLOT routine not implemented: pgqfs\n"); }
void cpgqhs(float *angle, float *sepn, float *phase) { WARN("WARNING: PGPLOT routine not implemented: pgqhs\n"); }
void cpgqid(int *id) { *id = 0; }
void cpgqinf(const char *item, char *value, int *value_length) { WARN("WARNING: PGPLOT routine not implemented: pgqinf\n"); }
void cpgqitf(int *itf) { WARN("WARNING: PGPLOT routine not implemented: pgqitf\n"); }
void cpgqls(int *ls) { WARN("WARNING: PGPLOT routine not implemented: pgqls\n"); }
void cpgqlw(int *lw) { WARN("WARNING: PGPLOT routine not implemented: pgqlw\n"); }
void cpgqndt(int *n) { WARN("WARNING: PGPLOT routine not implemented: pgqndt\n"); }
void cpgqpos(float *x, float *y) { WARN("WARNING: PGPLOT routine not implemented: pgqpos\n"); }
void cpgqtbg(int *tbci) { WARN("WARNING: PGPLOT routine not implemented: pgqtbg\n"); }
void cpgqtxt(float x, float y, float angle, float fjust, const char *text, float *xbox, float *ybox) { WARN("WARNING: PGPLOT routine not implemented: pgqtxt\n"); }
void cpgqvp(int units, float *x1, float *x2, float *y1, float *y2) {
	PLFLT x1d, x2d, y1d, y2d, xp, yp;
	PLINT xleng, yleng, xoff, yoff;

	plgvpd(&x1d, &x2d, &y1d, &y2d);
	printf("plgvpd: %f %f %f %f\n", x1d, x2d, y1d, y2d);
	if (units != 0) {
		plgpage(&xp, &yp, &xleng, &yleng, &xoff, &yoff);
		printf("%i %f %f %f %f %f %f\n", units, xp, yp, xleng, yleng, xoff, yoff);
		*x1 = x1d * xleng - xoff;
		*x2 = x2d * xleng - xoff;
		*y1 = y1d * yleng - yoff;
		*y2 = y2d * yleng - yoff; 
		if (units == 3) {
			return;
		} else if (units == 2) {
			*x1 = *x1 / (xp * mm_per_inch);
			*x2 = *x2 / (xp * mm_per_inch);
			*y1 = *y1 / (yp * mm_per_inch);
			*y2 = *y2 / (yp * mm_per_inch);
			return;
		} else if(units == 1) {
			*x1 /= xp;
			*x2 /= xp;
			*y1 /= yp;
			*y2 /= yp;
			return;
		}
	} else {
		printf("unknown units in pgqvp: %i\n", units);
	}
	*x1 = x1d;
	*x2 = x2d;
 	*y1 = y1d;
 	*y2 = y2d;
}
void cpgqvsz(int units, float *x1, float *x2, float *y1, float *y2) { WARN("WARNING: PGPLOT routine not implemented: pgqvsz\n"); }
void cpgqwin(float *x1, float *x2, float *y1, float *y2) { WARN("WARNING: PGPLOT routine not implemented: pgqwin\n"); }
void cpgrect(float x1, float x2, float y1, float y2) {
	PLFLT x[5] = { x1, x1, x2, x2, x1 }, y[5] = { y1, y2, y2, y1, y1 };
	plfill(4, x, y);
	if (cur_fillstyle == 2) plline(5, x, y);
}
float cpgrnd(float x, int *nsub) { WARN("WARNING: PGPLOT routine not implemented: pgrnd\n"); }
void cpgrnge(float x1, float x2, float *xlo, float *xhi) { WARN("WARNING: PGPLOT routine not implemented: pgrnge\n"); }
void cpgsah(int fs, float angle, float barb) { WARN("WARNING: PGPLOT routine not implemented: pgsah\n"); }
void cpgsave(void) {
	save_data s;
	plgfont(&s.font_family, &s.font_style, &s.font_weight);
	s.line_width = cur_width;
	s.line_style = cur_style;
	s.line_color = cur_color;
	savedata.push_back(s);
}
void cpgunsa(void) {
	save_data s = savedata.back();
	savedata.pop_back();
	plsfont(s.font_family, s.font_style, s.font_weight);
	cpgslw(s.line_width);
	cpgsls(s.line_style);
	cpgsci(s.line_color);
}
void cpgscf(int font) { plfont(font); }
void cpgsch(float size) { plschr(0., size * ch_fac); }
void cpgsci(int ci) {
	int ci2 = ci;
	int colours[] = {0,15,1,3,9,11,13,2,14,12,4,11,10,5,7,7}; //{0,15, 11,13,2, 1,3, 9,8,12,4,7,10,5,7,7}
	if (ci >= 0 && ci <=15) ci2 = colours[ci];
	cur_color = ci;
	plcol0(ci2);
}
void cpgscir(int icilo, int icihi) { WARN("WARNING: PGPLOT routine not implemented: pgscir\n"); }
void cpgsclp(int state) { WARN("WARNING: PGPLOT routine not implemented: pgsclp\n"); }
void cpgscr(int ci, float cr, float cg, float cb) {
	int ri = int(cr*255);
	int gi = int(cg*255);
	int bi = int(cb*255);
	int ci2 = ci;
	int colours[] = {0,15,1,3,9,11,13,2,14,12,4,11,10,5,7,7}; //{0,15, 11,13,2, 1,3, 9,8,12,4,7,10,5,7,7}
	if (ci >= 0 && ci <=15) ci2 = colours[ci];
	if (ci2 > 15) plscmap0n(256);  // Allows indices 0-255
  
	plscol0(ci2, ri,gi,bi);
}
void cpgscrl(float dx, float dy) { WARN("WARNING: PGPLOT routine not implemented: pgscrl\n"); }
void cpgscrn(int ci, const char *name, int *ier) { WARN("WARNING: PGPLOT routine not implemented: pgscrn\n"); }
void cpgsfs(int fs) {
	int fs1 = fs;
	if (fs < 1 || fs > 4) fs1 = 1;
	int styles[4] = { 0,0,3,8 };
	if (fs == 2) {
		PLINT inc = 0, del = INT_MAX;
		plpat(1, &inc, &del);
	} else {
		plpsty(styles[fs1-1]);
	}
	cur_fillstyle = fs;
}
void cpgshls(int ci, float ch, float cl, float cs) { WARN("WARNING: PGPLOT routine not implemented: pgshls\n"); }
void cpgshs(float angle, float sepn, float phase) {
	PLINT inc, del;
	inc = (int)(angle * 10. + 0.5);   // Tenths of a degree
	del = (int)(sepn * 1000. + 0.5);  // Spacing in micrometers(!)
	plpat(1, &inc, &del);
}
void cpgsitf(int itf) { WARN("WARNING: PGPLOT routine not implemented: pgsitf\n"); }
void cpgslct(int id) {
#ifdef DPQT
    dpCommandQFitsView("plplot", "show", id-1);
#else /* DPQT */
    WARN("WARNING: PGPLOT routine not implemented: pgslct\n");
#endif /* !DPQT */
}
void cpgsls(int ls) {
	int styles[] = {1,4,5,2,6};
  
	int ls1 = ls;   // 1: solid, 2: dashes, 3: dash-dotted, 4: dotted, 5: dash-dot-dot-dot
	if (ls1 < 1 || ls1 > 5) ls1 = 1;
	  // 1: solid, 2: short dashes, 3: long dashes, 4: long dashes, short gaps, 5: long-short dashes, 6: long-short dashes, long-short gaps, 7: ?, 8: ?
	cur_style = ls;
	pllsty(styles[ls1-1]);
}
void cpgslw(int lw) { cur_width = lw; plwidth(lw-1); }
void cpgstbg(int tbci) { WARN("WARNING: PGPLOT routine not implemented: pgstbg\n"); }
void cpgsubp(int nxsub, int nysub) { npanels = nxsub * nysub; cur_panel = 0; plssub(nxsub, nysub); }
void cpgsvp(float xleft, float xright, float ybot, float ytop) { pg_initplplot(); plvpor(xleft, xright, ybot, ytop); }
void cpgswin(float x1, float x2, float y1, float y2) { plwind(x1, x2, y1, y2); }
void cpgtbox(const char *xopt, float xtick, int nxsub, const char *yopt, float ytick, int nysub) { plbox(xopt, xtick, nxsub, yopt, ytick, nysub); } // TODO: handle options for time formats
void cpgtext(float x, float y, const char *text) { plptex(x, y, 1., 0., 0., pg2pltext(text).c_str()); }
void cpgtick(float x1, float y1, float x2, float y2, float v, float tikl, float tikr, float disp, float orient, const char *str) { WARN("WARNING: PGPLOT routine not implemented: pgtick\n"); }
void cpgupdt(void) { WARN("WARNING: PGPLOT routine not implemented: pgupdt\n"); }
void cpgvect(const float *a, const float *b, int idim, int jdim, int i1, int i2, int j1, int j2, float c, int nc, const float *tr, float blank) { WARN("WARNING: PGPLOT routine not implemented: pgvect\n"); }
void cpgvsiz(float xleft, float xright, float ybot, float ytop) { plsvpa(xleft, xright, ybot, ytop); }
void cpgvstd(void) { WARN("WARNING: PGPLOT routine not implemented: pgvstd\n"); }
void cpgwedg(const char *side, float disp, float width, float fg, float bg, const char *label) { WARN("WARNING: PGPLOT routine not implemented: pgwedg\n"); }
void cpgwnad(float x1, float x2, float y1, float y2) { plvasp(fabs((y2-y1)/(x2-x1))); plwind(x1,x2,y1,y2); }

#endif /* HAS_PG2PLPLOT */
