/*
 * Copyright 2010 Google Inc.
 * 
 * Licensed 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 com.google.gwt.user.cellview.client;

import java.util.ArrayList;
import java.util.List;

/**
 * An ordered list containing the sort history of {@link Column}s in a table.
 * The 0th item is the {@link ColumnSortInfo} of the most recently sorted
 * column.
 */
public class ColumnSortList {

  /**
   * Information about the sort order of a specific column in a table.
   */
  public static class ColumnSortInfo {

    private final boolean ascending;
    private final Column<?, ?> column;

    /**
     * Construct a new {@link ColumnSortInfo}.
     * 
     * @param column the column index
     * @param ascending true if sorted ascending
     */
    public ColumnSortInfo(Column<?, ?> column, boolean ascending) {
      this.column = column;
      this.ascending = ascending;
    }

    /**
     * Default constructor used for RPC.
     */
    ColumnSortInfo() {
      this(null, true);
    }

    /**
     * Check if this object is equal to another. The objects are equal if the
     * column and ascending values are the equal.
     * 
     * @param obj the object to check for equality
     * @return true if objects are the same
     */
    @Override
    public boolean equals(Object obj) {
      if (obj == this) {
        return true;
      } else if (!(obj instanceof ColumnSortInfo)) {
        return false;
      }

      ColumnSortInfo other = (ColumnSortInfo) obj;
      return equalsOrBothNull(getColumn(), other.getColumn())
          && isAscending() == other.isAscending();
    }

    /**
     * Get the {@link Column} that was sorted.
     * 
     * @return the {@link Column}
     */
    public Column<?, ?> getColumn() {
      return column;
    }

    @Override
    public int hashCode() {
      return 31 * (column == null ? 0 : column.hashCode())
          + (ascending ? 1 : 0);
    }

    /**
     * Check if the column was sorted in ascending or descending order.
     * 
     * @return true if ascending, false if descending
     */
    public boolean isAscending() {
      return ascending;
    }

    private boolean equalsOrBothNull(Object a, Object b) {
      return a == null ? b == null : a.equals(b);
    }
  }

  /**
   * The delegate that handles modifications to the list.
   */
  public static interface Delegate {

    /**
     * Called when the list is modified.
     */
    void onModification();
  }

  /**
   * The delegate that handles modifications.
   */
  private final Delegate delegate;

  /**
   * A List used to manage the insertion/removal of {@link ColumnSortInfo}.
   */
  private final List<ColumnSortInfo> infos = new ArrayList<ColumnSortInfo>();

  /**
   * Construct a new {@link ColumnSortList} without a {@link Delegate}.
   */
  public ColumnSortList() {
    this(null);
  }

  /**
   * Construct a new {@link ColumnSortList} with the specified {@link Delegate}.
   * 
   * @param delegate the {@link Delegate} to inform of modifications
   */
  public ColumnSortList(Delegate delegate) {
    this.delegate = delegate;
  }

  /**
   * Removes all of the elements from this list.
   */
  public void clear() {
    infos.clear();
    fireDelegate();
  }

  /**
   * Check if the specified object equals this list. Two {@link ColumnSortList}
   * are equals if they are the same size, and all entries are
   * <code>equals</code> and in the same order.
   */
  @Override
  public boolean equals(Object obj) {
    if (obj == this) {
      return true;
    } else if (!(obj instanceof ColumnSortList)) {
      return false;
    }

    // Check the size of the lists.
    ColumnSortList other = (ColumnSortList) obj;
    return infos.equals(other.infos);
  }

  /**
   * Get the {@link ColumnSortInfo} at the specified index.
   * 
   * @param index the index
   * @return the {@link ColumnSortInfo}
   */
  public ColumnSortInfo get(int index) {
    return infos.get(index);
  }

  @Override
  public int hashCode() {
    return 31 * infos.hashCode() + 13;
  }

  /**
   * Inserts the specified {@link ColumnSortInfo} at the specified position in
   * this list. If the column already exists in the sort info, the index will be
   * adjusted to account for any removed entries.
   * 
   * @param sortInfo the {@link ColumnSortInfo} to add
   */
  public void insert(int index, ColumnSortInfo sortInfo) {
    if (sortInfo == null) {
      throw new IllegalArgumentException("sortInfo cannot be null");
    }

    // Remove sort info for duplicate columns
    Column<?, ?> column = sortInfo.getColumn();
    for (int i = 0; i < infos.size(); i++) {
      ColumnSortInfo curInfo = infos.get(i);
      if (curInfo.getColumn() == column) {
        infos.remove(i);
        if (i < index) {
          index--;
        }
        i--;
      }
    }

    // Insert the new sort info
    infos.add(index, sortInfo);
    fireDelegate();
  }

  /**
   * Push a {@link Column} onto the list at index zero, setting ascending to
   * true. If the column already exists, it will be removed from its current
   * position and placed at the start of the list. If the Column is already at
   * the start of the list, its ascending bit will be flipped (ascending to
   * descending and vice versa).
   * 
   * @param column the {@link Column} to push
   * @return the {@link ColumnSortInfo} that was pushed
   */
  public ColumnSortInfo push(Column<?, ?> column) {
    // If the column matches the primary column, toggle the order.
    boolean ascending = true;
    if (size() > 0 && get(0).getColumn() == column) {
      ascending = !get(0).isAscending();
    }

    // Push the new column.
    ColumnSortInfo toRet = new ColumnSortInfo(column, ascending);
    push(toRet);
    return toRet;
  }

  /**
   * Push a {@link ColumnSortInfo} onto the list at index zero. If the column
   * already exists, it will be removed from its current position and placed at
   * the start of the list.
   * 
   * @param sortInfo the {@link ColumnSortInfo} to push
   */
  public void push(ColumnSortInfo sortInfo) {
    insert(0, sortInfo);
  }

  /**
   * Remove a {@link ColumnSortInfo} from the list.
   * 
   * @param sortInfo the {@link ColumnSortInfo} to remove
   */
  public boolean remove(ColumnSortInfo sortInfo) {
    boolean toRet = infos.remove(sortInfo);
    fireDelegate();
    return toRet;
  }

  /**
   * Get the size of the list.
   * 
   * @return the number of {@link ColumnSortInfo} in the list
   */
  public int size() {
    return infos.size();
  }

  private void fireDelegate() {
    if (delegate != null) {
      delegate.onModification();
    }
  }
}
