package nxm.sys.libg;

import nxm.sys.inc.Constants;

/** A class to draw Polar views. Uses a look-up-table for speed on sines and cosines.

    @author  Jeff Schoen
 */
public class ViewPolar extends View {

  private float[] tsin,tcos,dtsin,dtcos;
  private static final int ndeg=725;

  /** Construct a new ViewPolar
      @param MP the MPlot associated with this view
   */
  public ViewPolar (MPlot MP) {
    super(MP);
    prepTables();
  }

  /** Fill in the sincos lookup tables */
  private void prepTables () {
    tsin = new float[ndeg];
    tcos = new float[ndeg];
    dtsin = new float[ndeg];
    dtcos = new float[ndeg];
    for (int i=0; i<ndeg; i++) {
      tsin[i] = (float)Math.sin( Constants.DEG2RAD * (double)i );
      tcos[i] = (float)Math.cos( Constants.DEG2RAD * (double)i );
    }
    for (int i=0; i<ndeg-1; i++) {
      dtsin[i] = tsin[i+1]-tsin[i];
      dtcos[i] = tcos[i+1]-tcos[i];
    }
  }

  @Override
  public int rwc2pix (float[] buf, int off, int dim, int npts, Pix pix,
                      double xstart, double xdelta) {
    // THIS METHOD IS IDENTICAL TO THE ONE THAT USES A float[] BUFFER FOR INPUT
    int i,j=off,n=pix.setSize(npts),xoff=off/dim; int[] pax=pix.x, pay=pix.y;
    double mxx=MP.mxx, myy=MP.myy, mxb=MP.mxb, myb=MP.myb;
    double x=xstart+xoff*xdelta;
    for (i=0; i<n; i++,j+=dim) {
      double theta = x*DEG2RAD; x+=xdelta;
      pax[i] = (int)(buf[j]*Math.cos(theta)*mxx + mxb);
      pay[i] = (int)(buf[j]*Math.sin(theta)*myy + myb);
    }
    return n;
  }

  @Override
  public int rwc2pix (double[] buf, int off, int dim, int npts, Pix pix,
                      double xstart, double xdelta) {
    // THIS METHOD IS IDENTICAL TO THE ONE THAT USES A float[] BUFFER FOR INPUT
    int i,j=off,n=pix.setSize(npts),xoff=off/dim; int[] pax=pix.x, pay=pix.y;
    double mxx=MP.mxx, myy=MP.myy, mxb=MP.mxb, myb=MP.myb;
    double x=xstart+xoff*xdelta;
    for (i=0; i<n; i++,j+=dim) {
      double theta = x*DEG2RAD; x+=xdelta;
      pax[i] = (int)(buf[j]*Math.cos(theta)*mxx + mxb);
      pay[i] = (int)(buf[j]*Math.sin(theta)*myy + myb);
    }
    return n;
  }

  @Override
  public int rwc2pix (float[] buf, int off, int dim, int npts, Pix pix) {
    int i,j=off,n=pix.setSize(npts),itheta; int[] pax=pix.x, pay=pix.y;
    float atheta,ptheta,r,ct,st;
    double mxx=MP.mxx, myy=MP.myy, mxb=MP.mxb, myb=MP.myb;
    for (i=0; i<n; i++,j+=dim) {
      atheta = buf[j] + 360.0f;
      itheta = (int)atheta;
      ptheta = atheta-(float)itheta;
      ct = tcos[itheta] + ptheta*dtcos[itheta];
      st = tsin[itheta] + ptheta*dtsin[itheta];
      r = buf[j+1];
      pax[i] = (int)(r*ct*mxx + mxb);
      pay[i] = (int)(r*st*myy + myb);
    }
    return n;
  }

  @Override
  public int rwc2pix (double[] buf, int off, int dim, int npts, Pix pix) {
    int i,j=off,n=pix.setSize(npts),itheta; int[] pax=pix.x, pay=pix.y;
    double atheta,ptheta,r,ct,st;
    double mxx=MP.mxx, myy=MP.myy, mxb=MP.mxb, myb=MP.myb;
    for (i=0; i<n; i++,j+=dim) {
      atheta = buf[j] + 360.0f;
      itheta = (int)atheta;
      ptheta = atheta-(double)itheta;
      ct = tcos[itheta] + ptheta*dtcos[itheta];
      st = tsin[itheta] + ptheta*dtsin[itheta];
      r = buf[j+1];
      pax[i] = (int)(r*ct*mxx + mxb);
      pay[i] = (int)(r*st*myy + myb);
    }
    return n;
  }

  @Override
  int rwc2pix (double[] buf, int off, int dim, int npts, Pix pix, boolean isFill) {
    // Use previous implementation of rwc2pix since 3.9.2
    return rwc2pix (buf, off, dim, npts, pix);
  }

  @Override
  public int rwc2dpix (double[] buf, int off, int dim, int npts, DPix pix) {
    int i,j=off,n=pix.setSize(npts),itheta;
    double[] pax=pix.x, pay=pix.y;
    double atheta,ptheta,r,ct,st;
    double mxx=MP.mxx, myy=MP.myy, mxb=MP.mxb, myb=MP.myb;
    for (i=0; i<n; i++,j+=dim) {
      atheta = buf[j] + 360.0f;
      itheta = (int) atheta;
      ptheta = atheta-(double)itheta;
      ct = tcos[itheta] + ptheta*dtcos[itheta];
      st = tsin[itheta] + ptheta*dtsin[itheta];
      r = buf[j+1];
      pax[i] = r*ct*mxx + mxb;
      pay[i] = r*st*myy + myb;
    }
    return n;
  }
}
