/*
 * Copyright 2009-2010 Yuichiro Moriguchi
 *
 * 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 net.morilib.awk.nano;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * awkiumの名前空間を指定するクラスです。<br />
 * awkiumにおいて、名前空間は以下のように表されます。
 * <pre>
 * path.of.awkium.name
 * </pre>
 * 
 * @author MORIGUCHI, Yuichiro 2013/03/10
 */
public final class AwkLocation {

	private List<String> path;
	private boolean root;

	/**
	 * 名前空間の場所を生成します。
	 * 
	 * @param root ルートを基点とするときtrueとする
	 * @param path 名前空間の場所
	 */
	public AwkLocation(boolean root, List<String> path) {
		this.root = root;
		this.path = new ArrayList<String>(path);
	}

	/**
	 * 名前空間の場所を生成します。
	 * 
	 * @param root ルートを基点とするときtrueとする
	 * @param path 名前空間の場所
	 */
	public AwkLocation(boolean root, String... path) {
		this.root = root;
		this.path = Arrays.asList(path);
	}

	/**
	 * 名前空間の場所を生成します。
	 * 
	 * @param path 名前
	 */
	public AwkLocation(String name) {
		this(false, name);
	}

	/**
	 * 名前空間の名前を取得します。<br />
	 * 例: パスpath.of.awkium.nameのとき、
	 * <pre>
	 * getName() → name
	 * </pre>
	 */
	public String getName() {
		return path.get(path.size() - 1);
	}

	/**
	 * 名前空間のパスの長さを取得します。
	 */
	public int sizeOfPath() {
		return path.size();
	}

	/**
	 * x番目の長さのパス名を取得します。<br />
	 * 例: パスpath.of.awkium.nameのとき、
	 * <pre>
	 * getPathOf(0) → path
	 * getPathOf(1) → of
	 * getPathOf(2) → awkium
	 * getPathOf(3) → name
	 * </pre>
	 */
	public String getPathOf(int x) {
		return path.get(x);
	}

	/**
	 * パスがルートから始まるときtrueを得ます。
	 */
	public boolean isRoot() {
		return root;
	}

	/**
	 * 単純な名前(パスの長さが1つ)のときtrueを得ます。
	 */
	public boolean isSimpleName() {
		return path.size() == 1;
	}

	/* (non-Javadoc)
	 * @see java.lang.Object#hashCode()
	 */
	public int hashCode() {
		int h = path.hashCode();

		return root ? -h : h;
	}

	/* (non-Javadoc)
	 * @see java.lang.Object#equals(java.lang.Object)
	 */
	public boolean equals(Object o) {
		if(o instanceof AwkLocation) {
			return (path.equals(((AwkLocation)o).path) &&
					root == ((AwkLocation)o).root);
		}
		return false;
	}

	/* (non-Javadoc)
	 * @see java.lang.Object#toString()
	 */
	public String toString() {
		StringBuffer b = new StringBuffer();
		String d = root ? "." : "";

		for(String s : path) {
			b.append(d).append(s);
			d = ".";
		}
		return b.toString();
	}

}
