// Copyright 2008 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.gwtorm.client;

import java.io.Serializable;

/**
 * Abstract key type using a single short value.
 * <p>
 * Applications should subclass this type to create their own entity-specific
 * key classes.
 *
 * @param <P> the parent key type. Use {@link Key} if no parent key is needed.
 */
@SuppressWarnings("serial")
public abstract class ShortKey<P extends Key<?>> implements Key<P>,
    Serializable {
  /**
   * @return id of the entity instance.
   */
  public abstract short get();

  /** @param newValue the new value of this key. */
  protected abstract void set(short newValue);

  /**
   * @return the parent key instance; null if this is a root level key.
   */
  public P getParentKey() {
    return null;
  }

  @Override
  public int hashCode() {
    int hc = get();
    if (getParentKey() != null) {
      hc *= 31;
      hc += getParentKey().hashCode();
    }
    return hc;
  }

  @Override
  public boolean equals(final Object b) {
    if (b == null || b.getClass() != getClass()) {
      return false;
    }

    final ShortKey<P> q = cast(b);
    return get() == q.get() && KeyUtil.eq(getParentKey(), q.getParentKey());
  }

  @Override
  public String toString() {
    final StringBuffer r = new StringBuffer();
    if (getParentKey() != null) {
      r.append(getParentKey().toString());
      r.append(',');
    }
    r.append(get());
    return r.toString();
  }

  public void fromString(final String in) {
    set(Short.parseShort(KeyUtil.parseFromString(getParentKey(), in)));
  }

  @SuppressWarnings("unchecked")
  private static <A extends Key<?>> ShortKey<A> cast(final Object b) {
    return (ShortKey<A>) b;
  }
}
