package jetbrains.mps.internal.collections.runtime;

/*Generated by MPS */

import java.util.Map;
import java.io.Serializable;
import java.util.HashMap;
import jetbrains.mps.internal.collections.runtime.impl.NullMapSequence;

public class MapSequence<U, V> extends AbstractMapSequence<U, V> implements IMapSequence<U, V>, Map<U, V>, Serializable {
  private static final long serialVersionUID = -3900727585622019317L;
  protected MapSequence(Map<U, V> map) {
    super(map);
  }
  public static <P, Q> MapSequenceInitializer<P, Q> fromKeysArray(P... keys) {
    Map<P, Q> map = new HashMap<P, Q>();
    return new MapSequenceInitializer<P, Q>(new MapSequence<P, Q>(map), keys);
  }
  /**
   * 
   * @deprecated replaced by fromMapAndEntryArray, which works better with inference
   */
  @Deprecated
  public static <P, Q> MapSequenceInitializer<P, Q> fromMapAndKeysArray(Map<P, Q> map, P... keys) {
    return new MapSequenceInitializer<P, Q>(new MapSequence<P, Q>(map), keys);
  }
  public static <P, Q> IMapSequence<P, Q> fromMapAndEntryArray(Map<P, Q> map, Map.Entry<? extends P, ? extends Q>... entries) {
    MapSequence<P, Q> sequence = new MapSequence<P, Q>(map);
    for (Map.Entry<? extends P, ? extends Q> entry : entries) {
      sequence.put(entry.getKey(), entry.getValue());
    }
    return sequence;
  }
  public static <P, Q> IMapSequence<P, Q> fromArray(IMapping<P, Q>... mappings) {
    Map<P, Q> map = new HashMap<P, Q>();
    for (IMapping<P, Q> mp : mappings) {
      map.put(mp.key(), mp.value());
    }
    return new MapSequence<P, Q>(map);
  }
  @SuppressWarnings(value = "unchecked")
  public static <P, Q> IMapSequence<P, Q> fromIterable(Iterable<IMapping<P, Q>> iterable) {
    if (iterable instanceof IMapSequence) {
      return (IMapSequence<P, Q>) iterable;
    }
    Map<P, Q> map = new HashMap<P, Q>();
    for (IMapping<P, Q> mpng : iterable) {
      map.put(mpng.key(), mpng.value());
    }
    return new MapSequence<P, Q>(map);
  }
  public static <P, Q> IMapSequence<P, Q> fromMap(Map<P, Q> map) {
    if (Sequence.USE_NULL_SEQUENCE) {
      if (map == null) {
        return NullMapSequence.<P,Q>instance();
      }
    }
    if (map instanceof IMapSequence) {
      return (IMapSequence<P, Q>) map;
    }
    return new MapSequence<P, Q>(map);
  }
  public static class MapSequenceInitializer<P, Q> {
    private final P[] keys;
    private final IMapSequence<P, Q> mapSeq;
    protected MapSequenceInitializer(IMapSequence<P, Q> mapSeq, P... keys) {
      this.mapSeq = mapSeq;
      this.keys = keys;
    }
    public IMapSequence<P, Q> withValues(Q... values) {
      for (int i = 0; i < keys.length && i < values.length; i++) {
        mapSeq.put(keys[i], values[i]);
      }
      return mapSeq;
    }
  }
}
