/**
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

package org.netbeans.lib.terminalemulator;

/**
 * A cartesian coordinate class, similar to Point.
 * The equivalent of 'offset' in swing.text.Document.
 * <br>
 * Rows are 0-origin, columns are 0-origin.
 * <p>
 * Why not the regular Java Point? Because ...
 * <ul>
 * <li>Point with 'x' and 'y' is not as clear.
 * <li>Point doesn't implement Comparable, which we depend on a lot.
 * </ul>
 */

public final class Coord implements Comparable<Coord> {
    public int row;
    public int col;

    /**
     * Create a Coord at the origin (top-left)
     */
    public Coord() {
	this.row = 0;
	this.col = 0;
    } 

    private Coord(int row, int col) {
	// Note this is flipped from Points(x, y) sense
	this.row = row;
	this.col = col;
    } 

    public static Coord make(int row, int col) {
	// 'row' is in absolute coordinates
	return new Coord(row, col);
    }

    public Coord(Coord coord) {
	this.row = coord.row;
	this.col = coord.col;
    } 

    Coord(BCoord coord, int bias) {
	this.row = coord.row + bias;
	this.col = coord.col;
    }

    BCoord toBCoord(int bias) {
	int new_row = row - bias;
	if (new_row < 0)
	    return new BCoord(0, 0);	// we're out of history
	else
	    return new BCoord(new_row, col);
    }

    public void copyFrom(Coord src) {
	this.row = src.row;
	this.col = src.col;
    } 

    // Overrides of Object:

    @Override
    public Object clone() {
	return new Coord(row, col);
    } 

    @Override
    public String toString() {
	return "(r=" + row + ",c=" + col + ")";	// NOI18N
    } 

    /**
     * Examples:
     * To satisfy Comparable.
     * <p>
     * <pre>
     * a &lt b	=== a.compareTo(b) &lt 0
     * a &gt= b	=== a.compareTo(b) &gt= 0
     * </pre>
     */
    @Override
    public int compareTo(Coord that) throws ClassCastException {
	// -1 or negative  -> this < o
	//  0              -> this == o
	// +1 or positive  -> this > o

	if (this.row < that.row)
	    return -1;
	else if (this.row > that.row)
	    return +1;
	else {
	    return this.col - that.col;
	}
    } 

    /* OLD public */ void clip(int rows, int cols, int bias) {
	// BE CAREFUL and clip view Coords with a view box and buffer
	// Coords with a buffer box!
	/* OLD
	if (row < 0)
	    row = 0;
	else if (row > rows)
	    row = rows;
	*/

	if (row < bias)
	    row = bias;
	else if (row > bias + rows)
	    row = bias + rows;

	if (col < 0)
	    col = 0;
	else if (col > cols)
	    col = cols;
    }
} 
