/*
 * 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;

import java.util.HashSet;
import java.util.Set;

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

  private Object curKey;
  private T curSelection;

  // Pending selection change
  private boolean newSelected;
  private T newSelectedItem = 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 item
   *          should act as its own key
   */
  public SingleSelectionModel(ProvidesKey<T> keyProvider) {
    super(keyProvider);
  }

  @Override
  public void clear() {
    setSelected(getSelectedObject(), false);
  }

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

  @Override
  public Set<T> getSelectedSet() {
    Set<T> set = new HashSet<T>();
    T item = getSelectedObject();
    if (item != null) {
      set.add(item);
    }
    return set;
  }

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

  @Override
  public void setSelected(T item, boolean selected) {
    // If we are deselecting an item that isn't actually selected, ignore it.
    if (!selected) {
      Object oldKey = newSelectedPending ? getKey(newSelectedItem) : curKey;
      Object newKey = getKey(item);
      if (!equalsOrBothNull(oldKey, newKey)) {
        return;
      }
    }
    newSelectedItem = item;
    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(newSelectedItem);
    boolean sameKey = equalsOrBothNull(curKey, key);
    boolean changed = false;
    if (newSelected) {
      changed = !sameKey;
      curSelection = newSelectedItem;
      curKey = key;
    } else if (sameKey) {
      changed = true;
      curSelection = null;
      curKey = null;
    }

    newSelectedItem = null;
    newSelectedPending = false;

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