/* ====================================================================
   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.apache.poi.ss.formula.ptg;

import org.apache.poi.ss.SpreadsheetVersion;
import org.apache.poi.ss.util.AreaReference;
import org.apache.poi.ss.util.CellReference;
import org.apache.poi.util.BitField;
import org.apache.poi.util.BitFieldFactory;
import org.apache.poi.util.LittleEndianInput;
import org.apache.poi.util.LittleEndianOutput;

/**
 * Specifies a rectangular area of cells A1:A4 for instance.
 * @author  andy
 * @author Jason Height (jheight at chariot dot net dot au)
 */
public abstract class AreaPtgBase extends OperandPtg implements AreaI {
    /**
     * TODO - (May-2008) fix subclasses of AreaPtg 'AreaN~' which are used in shared formulas.
     * see similar comment in ReferencePtg
     */
    protected final RuntimeException notImplemented() {
        return new RuntimeException("Coding Error: This method should never be called. This ptg should be converted");
    }

    /** zero based, unsigned 16 bit */
    private int field_1_first_row;
    /** zero based, unsigned 16 bit */
    private int field_2_last_row;
    /** zero based, unsigned 8 bit */
    private int field_3_first_column; //BitFields: (first row relative, first col relative, first column number)
    /** zero based, unsigned 8 bit */
    private int field_4_last_column; //BitFields: (last row relative, last col relative, last column number)

    private final static BitField rowRelative = BitFieldFactory.getInstance(0x8000);
    private final static BitField colRelative = BitFieldFactory.getInstance(0x4000);
    private final static BitField columnMask  = BitFieldFactory.getInstance(0x3FFF);

    protected AreaPtgBase() {
        // do nothing
    }

    protected AreaPtgBase(AreaReference ar) {
        CellReference firstCell = ar.getFirstCell();
        CellReference lastCell = ar.getLastCell();
        setFirstRow(firstCell.getRow());
        setFirstColumn(firstCell.getCol() == -1 ? 0 : firstCell.getCol());
        setLastRow(lastCell.getRow());
        setLastColumn(lastCell.getCol() == -1 ? 0xFF : lastCell.getCol());
        setFirstColRelative(!firstCell.isColAbsolute());
        setLastColRelative(!lastCell.isColAbsolute());
        setFirstRowRelative(!firstCell.isRowAbsolute());
        setLastRowRelative(!lastCell.isRowAbsolute());
    }

    protected AreaPtgBase(int firstRow, int lastRow, int firstColumn, int lastColumn,
            boolean firstRowRelative, boolean lastRowRelative, boolean firstColRelative, boolean lastColRelative) {

        if (lastRow >= firstRow) {
            setFirstRow(firstRow);
            setLastRow(lastRow);
            setFirstRowRelative(firstRowRelative);
            setLastRowRelative(lastRowRelative);
        } else {
            setFirstRow(lastRow);
            setLastRow(firstRow);
            setFirstRowRelative(lastRowRelative);
            setLastRowRelative(firstRowRelative);
        }

        if (lastColumn >= firstColumn) {
            setFirstColumn(firstColumn);
            setLastColumn(lastColumn);
            setFirstColRelative(firstColRelative);
            setLastColRelative(lastColRelative);
        } else {
            setFirstColumn(lastColumn);
            setLastColumn(firstColumn);
            setFirstColRelative(lastColRelative);
            setLastColRelative(firstColRelative);
        }
    }
    
    /**
     * Sort the first and last row and columns in-place to the preferred (top left:bottom right) order
     * Note: Sort only occurs when an instance is constructed or when this method is called.
     * 
     * <p>For example, <code>$E5:B$10</code> becomes <code>B5:$E$10</code></p>
     */
    public void sortTopLeftToBottomRight() {
        if (getFirstRow() > getLastRow()) {
            //swap first row and last row numbers and relativity
            //Note: cannot just swap the fields because row relativity is stored in fields 3 and 4
            final int firstRow = getFirstRow();
            final boolean firstRowRel = isFirstRowRelative();
            setFirstRow(getLastRow());
            setFirstRowRelative(isLastRowRelative());
            setLastRow(firstRow);
            setLastRowRelative(firstRowRel);
        }
        if (getFirstColumn() > getLastColumn()) {
            //swap first column and last column numbers and relativity
            //Note: cannot just swap the fields because row relativity is stored in fields 3 and 4
            final int firstCol = getFirstColumn();
            final boolean firstColRel = isFirstColRelative();
            setFirstColumn(getLastColumn());
            setFirstColRelative(isLastColRelative());
            setLastColumn(firstCol);
            setLastColRelative(firstColRel);
        }
    }

    protected final void readCoordinates(LittleEndianInput in)  {
        field_1_first_row = in.readUShort();
        field_2_last_row = in.readUShort();
        field_3_first_column = in.readUShort();
        field_4_last_column = in.readUShort();
    }
    protected final void writeCoordinates(LittleEndianOutput out) {
        out.writeShort(field_1_first_row);
        out.writeShort(field_2_last_row);
        out.writeShort(field_3_first_column);
        out.writeShort(field_4_last_column);
    }

    /**
     * @return the first row in the area
     */
    public final int getFirstRow() {
        return field_1_first_row;
    }

    /**
     * sets the first row
     * @param rowIx number (0-based)
     */
    public final void setFirstRow(int rowIx) {
        field_1_first_row = rowIx;
    }

    /**
     * @return last row in the range (x2 in x1,y1-x2,y2)
     */
    public final int getLastRow() {
        return field_2_last_row;
    }

    /**
     * @param rowIx last row number in the area
     */
    public final void setLastRow(int rowIx) {
        field_2_last_row = rowIx;
    }

    /**
     * @return the first column number in the area.
     */
    public final int getFirstColumn() {
        return columnMask.getValue(field_3_first_column);
    }

    /**
     * @return the first column number + the options bit settings unstripped
     */
    public final short getFirstColumnRaw() {
        return (short) field_3_first_column; // TODO
    }

    /**
     * @return whether or not the first row is a relative reference or not.
     */
    public final boolean isFirstRowRelative() {
        return rowRelative.isSet(field_3_first_column);
    }

    /**
     * sets the first row to relative or not
     * @param rel is relative or not.
     */
    public final void setFirstRowRelative(boolean rel) {
        field_3_first_column=rowRelative.setBoolean(field_3_first_column,rel);
    }

    /**
     * @return isrelative first column to relative or not
     */
    public final boolean isFirstColRelative() {
        return colRelative.isSet(field_3_first_column);
    }

    /**
     * set whether the first column is relative
     */
    public final void setFirstColRelative(boolean rel) {
        field_3_first_column=colRelative.setBoolean(field_3_first_column,rel);
    }

    /**
     * set the first column in the area
     */
    public final void setFirstColumn(int colIx) {
        field_3_first_column=columnMask.setValue(field_3_first_column, colIx);
    }

    /**
     * set the first column irrespective of the bitmasks
     */
    public final void setFirstColumnRaw(int column) {
        field_3_first_column = column;
    }

    /**
     * @return lastcolumn in the area
     */
    public final int getLastColumn() {
        return columnMask.getValue(field_4_last_column);
    }

    /**
     * @return last column and bitmask (the raw field)
     */
    public final short getLastColumnRaw() {
        return (short) field_4_last_column;
    }

    /**
     * @return last row relative or not
     */
    public final boolean isLastRowRelative() {
        return rowRelative.isSet(field_4_last_column);
    }

    /**
     * set whether the last row is relative or not
     * @param rel <code>true</code> if the last row relative, else
     * <code>false</code>
     */
    public final void setLastRowRelative(boolean rel) {
        field_4_last_column=rowRelative.setBoolean(field_4_last_column,rel);
    }

    /**
     * @return lastcol relative or not
     */
    public final boolean isLastColRelative() {
        return colRelative.isSet(field_4_last_column);
    }

    /**
     * set whether the last column should be relative or not
     */
    public final void setLastColRelative(boolean rel) {
        field_4_last_column=colRelative.setBoolean(field_4_last_column,rel);
    }

    /**
     * set the last column in the area
     */
    public final void setLastColumn(int colIx) {
        field_4_last_column=columnMask.setValue(field_4_last_column, colIx);
    }

    /**
     * set the last column irrespective of the bitmasks
     */
    public final void setLastColumnRaw(short column) {
        field_4_last_column = column;
    }
    protected final String formatReferenceAsString() {
        CellReference topLeft = new CellReference(getFirstRow(),getFirstColumn(),!isFirstRowRelative(),!isFirstColRelative());
        CellReference botRight = new CellReference(getLastRow(),getLastColumn(),!isLastRowRelative(),!isLastColRelative());

        if(AreaReference.isWholeColumnReference(SpreadsheetVersion.EXCEL97, topLeft, botRight)) {
            return (new AreaReference(topLeft, botRight)).formatAsString();
        }
        return topLeft.formatAsString() + ":" + botRight.formatAsString();
    }

    public String toFormulaString() {
        return formatReferenceAsString();
    }

    public byte getDefaultOperandClass() {
        return Ptg.CLASS_REF;
    }
}
