/*
 * 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.view.client;

import com.google.gwt.view.client.SelectionModel.AbstractSelectionModel;

/**
 * A simple selection model that allows only one object to be selected a a time.
 *
 * @param <T> the record data type
 */
public class SingleSelectionModel<T> extends AbstractSelectionModel<T> {

  private Object curKey;
  private T curSelection;

  // Pending selection change
  private boolean newSelected;
  private T newSelectedObject = null;
  private boolean newSelectedPending;

  /**
   * Constructs a SingleSelectionModel without a key provider.
   */
  public SingleSelectionModel() {
    super(null);
  }

  /**
   * Constructs a SingleSelectionModel with the given key provider.
   *
   * @param keyProvider an instance of ProvidesKey<T>, or null if the record
   *        object should act as its own key
   */
  public SingleSelectionModel(ProvidesKey<T> keyProvider) {
    super(keyProvider);
  }

  /**
   * Gets the currently-selected object.
   *
   * @return the selected object
   */
  public T getSelectedObject() {
    resolveChanges();
    return curSelection;
  }

  public boolean isSelected(T object) {
    resolveChanges();
    if (curSelection == null || curKey == null || object == null) {
      return false;
    }
    return curKey.equals(getKey(object));
  }

  public void setSelected(T object, boolean selected) {
    // If we are deselecting a value that isn't actually selected, ignore it.
    if (!selected) {
      Object oldKey = newSelectedPending ? getKey(newSelectedObject) : curKey;
      Object newKey = getKey(object);
      if (!equalsOrBothNull(oldKey, newKey)) {
        return;
      }
    }
    newSelectedObject = object;
    newSelected = selected;
    newSelectedPending = true;
    scheduleSelectionChangeEvent();
  }

  @Override
  protected void fireSelectionChangeEvent() {
    if (isEventScheduled()) {
      setEventCancelled(true);
    }
    resolveChanges();
  }

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

  private void resolveChanges() {
    if (!newSelectedPending) {
      return;
    }

    Object key = getKey(newSelectedObject);
    boolean sameKey = equalsOrBothNull(curKey, key);
    boolean changed = false;
    if (newSelected) {
      changed = !sameKey;
      curSelection = newSelectedObject;
      curKey = key;
    } else if (sameKey) {
      changed = true;
      curSelection = null;
      curKey = null;
    }

    newSelectedObject = null;
    newSelectedPending = false;

    // Fire a selection change event.
    if (changed) {
      SelectionChangeEvent.fire(this);
    }
  }
}
