001/*
002 * Copyright (c) 2005 Einar Pehrson <einar@pehrson.nu>.
003 *
004 * This file is part of
005 * CleanSheets - a spreadsheet application for the Java platform.
006 *
007 * CleanSheets is free software; you can redistribute it and/or modify
008 * it under the terms of the GNU General Public License as published by
009 * the Free Software Foundation; either version 2 of the License, or
010 * (at your option) any later version.
011 *
012 * CleanSheets is distributed in the hope that it will be useful,
013 * but WITHOUT ANY WARRANTY; without even the implied warranty of
014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
015 * GNU General Public License for more details.
016 *
017 * You should have received a copy of the GNU General Public License
018 * along with CleanSheets; if not, write to the Free Software
019 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
020 */
021package csheets.core;
022
023import java.io.Serializable;
024
025/**
026 * An address in a spreadsheet that denotes to the location of a cell.
027 * @author Einar Pehrson
028 */
029public class Address implements Comparable<Address>, Serializable {
030
031        /** The unique version identifier used for serialization */
032        private static final long serialVersionUID = -1096697824364544991L;
033
034        /** The lowest character to be used in a column name */
035        public static final char LOWEST_CHAR = 'A';
036
037        /** The highest character to be used in a column name */
038        public static final char HIGHEST_CHAR = 'Z';
039
040        /** The column of the spreadsheet that the address refers to */
041        private int column;
042
043        /** The row of the spreadsheet that the address refers to */
044        private int row;
045
046        /** A string representation of the address */
047        private transient String string;
048
049        /**
050         * Creates a new address from the given column and row indices.
051         * @param column the column of the address
052         * @param row the row of the address
053         */
054        public Address(int column, int row) {
055                this.column = column;
056                this.row = row;
057        }
058
059        /**
060         * Returns the column of the address.
061         * @return the column of the address
062         */
063        public int getColumn() {
064                return column;
065        }
066
067        /**
068         * Returns the row of the address.
069         * @return the row of the address
070         */
071        public int getRow() {
072                return row;
073        }
074
075        /**
076         * Returns whether the other object is an address with
077         * the same column and row coordinates as this address.
078         * @param other the object to check for equality
079         * @return true if the objects are equal
080         */
081        public boolean equals(Object other) {
082                if (!(other instanceof Address) || other == null)
083                        return false;
084                Address otherAddress = (Address)other;
085                return row == otherAddress.getRow()
086                        && column == otherAddress.getColumn();
087        }
088
089        /**
090         * Returns the hash code of the address.
091         * @return an int with the column in the 16 high bits, row in the low 16.
092         */
093        public int hashCode() {
094                return (column << 16) + row;
095        }
096
097        /**
098         * Compares this address with the given address for order.
099         * Ordering is first done on the addresses' columns, then on their rows.
100         * @param address the address to compared to
101         * @return a negative integer, zero, or a positive integer as this object is less than, equal to, or greater than the specified object.
102         */
103        public int compareTo(Address address) {
104                int columnDiff = column - address.getColumn();
105                if (columnDiff != 0)
106                        return columnDiff;
107                else 
108                        return row - address.getRow();
109        }
110
111        /**
112         * Returns a string representation of the address on the form "B22",
113         * composed of the letter of the column and number of the row that
114         * intersect to form the address.        
115         * @return a string representation of the address
116         */
117        public String toString() {
118                if (string == null) {
119                        String columnStr;
120                        int tempColumn = column;
121                        for (columnStr = ""; tempColumn >= 0; tempColumn = tempColumn
122                                        / (HIGHEST_CHAR - LOWEST_CHAR + 1) - 1)
123                                columnStr = (char)((char)(tempColumn % (HIGHEST_CHAR
124                                        - LOWEST_CHAR + 1)) + LOWEST_CHAR) + columnStr;
125                        string = columnStr + (row + 1);
126                }
127                return new String(string);
128        }
129}