package nxm.sys.libg;

/** A class to define a Pixel Buffer for {@link MPlot}, {@link View}, and {@link Layer}. This is
    used for vector line drawing and is not a replacement a buffered image.

    @author Jeff Schoen
 */
public class Pix extends Object {

  /** Pixel conversion flag used exclusively by {@link MPlot} and subclasses of {@link View}.
      <pre>
        CHECK    - Use special handling for non-visible points in {@link ViewGeo}.
        CLIP     - Use automatic bounds clipping with {@link View} (handles wrapping
                   at -180/180 for LatLon and Mercator views).
        HIDE     - <i>Not Used</i>
        NORM     - Use special normalization for drawing grid in XYZ view.
        KEEP     - Keep non-visible points, as the line between them may be visible.
                   Do not use with CHECK.
        NEVERCLIP- Never clip, even when in LatLonContinuous and seems object crosses new bounds
        FULLKEEP - Keep this point because other corner of the object is visible
      </pre>
   */
  public static final int CHECK=0x1, CLIP=0x2, HIDE=0x4, NORM=0x8, KEEP=0x10;
  static final int NEVERCLIP=0x20, FULLKEEP=0x40;

  /** array size - max */            public int max;
  /** offset */                      public int off;
  /** number of pts with max cap */  public int n;
  /** flags */                       public int flags;
  /** x pixel values */              public int[] x;
  /** y pixel values */              public int[] y;
  /** z values */                    public float[] z;

  // This is package-private, only used by MPlot and View
  /** any saved? */                  boolean save;
  /** Save values X */               int[]   sx = new int[2];
  /** Save values Y */               int[]   sy = new int[2];
  /** Save values Z */               float[] sz = new float[2];

  /** Pix constructor
   *
   *  @param maxsize maximum size
   *  @param flags   flags
   */
  public Pix (int maxsize, int flags) {
    max = maxsize+1;
    x = new int[max];
    y = new int[max];
    z = new float[max];
    setFlags(flags);
  }

  /** return how many points to do this pass and offset for next pass
   *  @param npts number of points requested
   *  @return npts done
   */
  public int setSize (int npts) {
    if (npts>max) { n=max; off=max-1; }
    else { n=npts; off=npts; }
    return n;
  }

  /** set flags (overwrites)
   *  @param mask flags mask
   */
  public void setFlags (int mask) { flags = mask; }

  /** set flag (OR)
   *  @param mask flag to OR with current flags
   */
  public void setFlag (int mask) { flags |= mask; }

  /** clear specific flag
   *  @param mask mask of flag to clear
   */
  public void clrFlag (int mask) { flags &= (~mask); }

  /** Get overall X and Y min and max from this Pix's x and y arrays
   *  @param num  number of sets to check
   *  @return overall X and Y min and max as an array
   */
  public int[] getXYMinMax(int num) {
    int r[] = {x[0],y[0],x[1],y[1]}; // since NeXtMidas 3.9.2 - start with first values rather than 0
    return (getXYMinMax(r,num));
  }

  /** Get overall X and Y min and max from a set of values
   *  @param ini  2D array with multiple sets of X and Y min and max
   *  @param num  number of sets to check
   *  @return overall X and Y min and max as an array
   */
  public int[] getXYMinMax(int[] ini, int num) {
    int xmin,xmax,ymin,ymax;
    xmin = ini[0];
    ymin = ini[1];
    xmax = ini[2];
    ymax = ini[3];

    for (int i = 0; i < num; i++) {
      xmax = Math.max(xmax, x[i]);
      xmin = Math.min(xmin, x[i]);
      ymax = Math.max(ymax, y[i]);
      ymin = Math.min(ymin, y[i]);
    }

    int[] retVal = new int[4];
    retVal[0] = xmin;
    retVal[1] = ymin;
    retVal[2] = xmax;
    retVal[3] = ymax;

    return (retVal);
  }

  /** Creates a string of the object. This is useful for debugging purposes. The format of the
      string returned by this method may change in future versions.

      @return A string describing the object.
   */
  @Override
  public String toString() {
    final StringBuffer str = new StringBuffer();

    str.append("Pix: {");

    for(int i = 0; i < n; i++) {
      str.append(" (");
      str.append(x[i]);
      str.append(',');
      str.append(y[i]);
      str.append(',');
      str.append(z[i]);
      str.append(')');
    }
    str.append(" }");

    return str.toString();
  }
}
