// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

/**
 * This class represents a pair of two objects, used by LinkedHashMap
 * to store a {key, value} in a list.
 */
class KeyValuePair<K, V> {
  KeyValuePair(this.key, this.value) {}

  final K key;
  V value;
}

/**
 * A LinkedHashMap is a hash map that preserves the insertion order
 * when iterating over the keys or the values. Updating the value of a
 * key does not change the order.
 */
class LinkedHashMapImplementation<K, V>
    implements LinkedHashMap<K, V> {
  DoubleLinkedQueue<KeyValuePair<K, V>> _list;
  HashMap<K, DoubleLinkedQueueEntry<KeyValuePair<K, V>>> _map;

  LinkedHashMapImplementation() {
    _map = new HashMap<K, DoubleLinkedQueueEntry<KeyValuePair<K, V>>>();
    _list = new DoubleLinkedQueue<KeyValuePair<K, V>>();
  }

  factory LinkedHashMapImplementation.from(Map<K, V> other) {
    Map<K, V> result = new LinkedHashMapImplementation<K, V>();
    other.forEach((K key, V value) { result[key] = value; });
    return result;
  }

  void operator []=(K key, V value) {
    if (_map.containsKey(key)) {
      _map[key].element.value = value;
    } else {
      _list.addLast(new KeyValuePair<K, V>(key, value));
      _map[key] = _list.lastEntry();
    }
  }

  V operator [](K key) {
    DoubleLinkedQueueEntry<KeyValuePair<K, V>> entry = _map[key];
    if (entry === null) return null;
    return entry.element.value;
  }

  V remove(K key) {
    DoubleLinkedQueueEntry<KeyValuePair<K, V>> entry = _map.remove(key);
    if (entry === null) return null;
    entry.remove();
    return entry.element.value;
  }

  V putIfAbsent(K key, V ifAbsent()) {
    V value = this[key];
    if ((this[key] === null) && !(containsKey(key))) {
      value = ifAbsent();
      this[key] = value;
    }
    return value;
  }

  Collection<K> getKeys() {
    List<K> list = new List<K>(length);
    int index = 0;
    _list.forEach(void _(KeyValuePair<K, V> entry) {
      list[index++] = entry.key;
    });
    assert(index == length);
    return list;
  }


  Collection<V> getValues() {
    List<V> list = new List<V>(length);
    int index = 0;
    _list.forEach(void _(KeyValuePair<K, V> entry) {
      list[index++] = entry.value;
    });
    assert(index == length);
    return list;
  }

  void forEach(void f(K key, V value)) {
    _list.forEach(void _(KeyValuePair<K, V> entry) {
      f(entry.key, entry.value);
    });
  }

  bool containsKey(K key) {
    return _map.containsKey(key);
  }

  bool containsValue(V value) {
    return _list.some(bool _(KeyValuePair<K, V> entry) {
      return (entry.value == value);
    });
  }

  int get length {
    return _map.length;
  }

  bool isEmpty() {
    return length == 0;
  }

  void clear() {
    _map.clear();
    _list.clear();
  }

  String toString() {
    return Maps.mapToString(this);
  }
}
