#include <stdio.h>
#include <stdlib.h>

#include "MGraph.h"
#include "c_parameter.h"

class MGraph_ScreenLocData
  {
public:
    MGraph_ScreenLocData();
    ~MGraph_ScreenLocData();
	int driver, no, precision;
    MGraph_Color backCol, penCol, fontCol, markCol, fillCol;
    MGraph_Size penSize, textSize;
  };

MGraph_ScreenContext::MGraph_ScreenContext(char *initTitle)
  : MGraph_Context(BLUE,YELLOW,YELLOW,RED,CYAN),
    title(initTitle)
  {
    impl = new MGraph_ScreenLocData();
    if (impl==0) return;
    zibset(impl->driver, impl->no, -1, CAPTION, title);
    if (backCol!=(impl->backCol))
      {
        zibset(impl->driver, impl->no, -1, BACKCOL, backCol);
        impl->backCol = backCol;
      }
    return;
  }

MGraph_ScreenContext::~MGraph_ScreenContext()
  {
    if (impl) delete impl;
    return;
  }

int MGraph_ScreenContext::PLine(float *x,float *y, int n)
  {
	if (impl->precision!=4)
	  { zibset(impl->driver, impl->no, -1, PREC, 4); impl->precision = 4; }
    if (penCol!=(impl->penCol))
      {
        zibset(impl->driver, impl->no, -1, PENCOL, penCol);
        impl->penCol = penCol;
      }
    if (penSize!=(impl->penSize))
      {
        zibset(impl->driver, impl->no, -1, PENSIZE, penSize);
        impl->penSize = penSize;
      }
	if (cc!=0) cc->PLine(x,y,n);
	return zibpl(impl->driver, impl->no, -1, (void*)x, (void*)y, n);
  }

int MGraph_ScreenContext::PLine(double *x,double *y, int n)
  {
	if (impl->precision!=8)
	  { zibset(impl->driver, impl->no, -1, PREC, 8); impl->precision = 8; }
    if (penCol!=(impl->penCol))
      {
        zibset(impl->driver, impl->no, -1, PENCOL, penCol);
        impl->penCol = penCol;
      }
    if (penSize!=(impl->penSize))
      {
        zibset(impl->driver, impl->no, -1, PENSIZE, penSize);
        impl->penSize = penSize;
      }
	if (cc!=0) cc->PLine(x,y,n);
	return zibpl(impl->driver, impl->no, -1, (void*)x, (void*)y, n);
  }

#ifdef LONG_DOUBLE
int MGraph_ScreenContext::PLine(long double *x,long double *y, int n)
  {
	if (impl->precision!=16)
	  { zibset(impl->driver, impl->no, -1, PREC, 16); impl->precision = 16; }
    if (penCol!=(impl->penCol))
      {
        zibset(impl->driver, impl->no, -1, PENCOL, penCol);
        impl->penCol = penCol;
      }
    if (penSize!=(impl->penSize))
      {
        zibset(impl->driver, impl->no, -1, PENSIZE, penSize);
        impl->penSize = penSize;
      }
	if (cc!=0) cc->PLine(x,y,n);
	return zibpl(impl->driver, impl->no, -1, (void*)x, (void*)y, n);
  }
#endif

int MGraph_ScreenContext::Fill(float *x,float *y, int n)
  {
	if (impl->precision!=4)
	  { zibset(impl->driver, impl->no, -1, PREC, 4); impl->precision = 4; }
    if (fillCol!=(impl->fillCol))
      {
        zibset(impl->driver, impl->no, -1, FILLCOL, fillCol);
        impl->fillCol = fillCol;
      }
	if (cc!=0) cc->Fill(x,y,n);
	return zibfl(impl->driver, impl->no, -1, (void*)x, (void*)y, n);
  }

int MGraph_ScreenContext::Fill(double *x,double *y, int n)
  {
	if (impl->precision!=8)
	  { zibset(impl->driver, impl->no, -1, PREC, 8); impl->precision = 8; }
    if (fillCol!=(impl->fillCol))
      {
        zibset(impl->driver, impl->no, -1, FILLCOL, fillCol);
        impl->fillCol = fillCol;
      }
	if (cc!=0) cc->Fill(x,y,n);
	return zibfl(impl->driver, impl->no, -1, (void*)x, (void*)y, n);
  }

#ifdef LONG_DOUBLE
int MGraph_ScreenContext::Fill(long double *x,long double *y, int n)
  {
	if (impl->precision!=16)
	  { zibset(impl->driver, impl->no, -1, PREC, 16); impl->precision = 16; }
    if (fillCol!=(impl->fillCol))
      {
        zibset(impl->driver, impl->no, -1, FILLCOL, fillCol);
        impl->fillCol = fillCol;
      }
	if (cc!=0) cc->Fill(x,y,n);
	return zibfl(impl->driver, impl->no, -1, (void*)x, (void*)y, n);
  }
#endif

int MGraph_ScreenContext::PMarker(float *x,float *y, int n, MGraph_Marker mark)
  {
	if (impl->precision!=4)
	  { zibset(impl->driver, impl->no, -1, PREC, 4); impl->precision = 4; }
    if (markCol!=(impl->markCol))
      {
        zibset(impl->driver, impl->no, -1, MARKCOL, markCol);
        impl->markCol = markCol;
      }
	if (cc!=0) cc->PMarker(x,y,n,mark);
	zibset(impl->driver, impl->no, -1, MARKER, mark);
	return zibpm(impl->driver, impl->no, -1, (void*)x, (void*)y, n);
  }

int MGraph_ScreenContext::PMarker(double *x,double *y, int n, MGraph_Marker mark)
  {
	if (impl->precision!=8)
	  { zibset(impl->driver, impl->no, -1, PREC, 8); impl->precision = 8; }
    if (markCol!=(impl->markCol))
      {
        zibset(impl->driver, impl->no, -1, MARKCOL, markCol);
        impl->markCol = markCol;
      }
	if (cc!=0) cc->PMarker(x,y,n,mark);
	zibset(impl->driver, impl->no, -1, MARKER, mark);
	return zibpm(impl->driver, impl->no, -1, (void*)x, (void*)y, n);
  }

#ifdef LONG_DOUBLE
int MGraph_ScreenContext::PMarker(long ouble *x,long double *y, int n, MGraph_Marker mark)
  {
	if (impl->precision!=16)
	  { zibset(impl->driver, impl->no, -1, PREC, 16); impl->precision = 16; }
    if (markCol!=(impl->markCol))
      {
        zibset(impl->driver, impl->no, -1, MARKCOL, markCol);
        impl->markCol = markCol;
      }
	if (cc!=0) cc->PMarker(x,y,n,mark);
	zibset(impl->driver, impl->no, -1, MARKER, mark);
	return zibpm(impl->driver, impl->no, -1, (void*)x, (void*)y, n);
  }
#endif

int MGraph_ScreenContext::Text(double x,double y, char *s)
  {
    if (fontCol!=(impl->fontCol))
      {
        zibset(impl->driver, impl->no, -1, FONTCOL, fontCol);
        impl->fontCol = fontCol;
      }
    if (textSize!=(impl->textSize))
      {
        zibset(impl->driver, impl->no, -1, FONTSIZE, textSize);
        impl->textSize = textSize;
      }
	if (cc!=0) cc->Text(x,y,s);
    return zibtx(impl->driver, impl->no, -1, x, y, s);
  }

void MGraph_ScreenContext::Clear()
  {
     zibclr(impl->driver, impl->no, -1);
  }

MGraph_ScreenLocData::MGraph_ScreenLocData()
  : backCol(UNDEF_COLOR), penCol(UNDEF_COLOR), fontCol(UNDEF_COLOR),
    markCol(UNDEF_COLOR), fillCol(UNDEF_COLOR), driver(SCREEN), no(-1),
    precision(SINGLE), penSize(UNDEF_SIZE), textSize(UNDEF_SIZE)
  {
	if (zibwop(&driver, &no))
	  {
	    zibset(driver, no, -1, BUFFER, OFF);
	    return;
	  }
	else abort();
  }

MGraph_ScreenLocData::~MGraph_ScreenLocData()
  {
	zibwcl(driver, no, 0);
	return;
  }
