package com.ejie.ab78.util;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

public class ComplexNode extends Node {

	private List<Node> nodeList = new ArrayList<Node>();

	private String label;

	ComplexNode() {
	}

	ComplexNode(String keyGroup) {
		this.setKeyGroup(keyGroup);
	}

	@Override
	public String toString() {
		int deep = 0;
		StringBuilder builder = new StringBuilder();
		String desc = this.label != null ? this.label : this.getKeyGroup() != null ? this.getKeyGroup() : "Root: ";
		builder.append(String.format("%s%n", desc));
		for (int i = 0; i < nodeList.size(); i++) {
			Node node = nodeList.get(i);
			builder.append(node.print(deep + 1));
		}
		return builder.toString();
	}

	public void add(Node node) {
		node.setParent(this);
		nodeList.add(node);
	}

	public Node find(String key) {
		if (getKeyGroup() != null && getKeyGroup().equalsIgnoreCase(key)) {
			return this;
		}
		for (Iterator<Node> iterator = nodeList.iterator(); iterator.hasNext();) {
			Node node = iterator.next();
			Node search = node.find(key);
			if (search != null) {
				return search;
			}
		}
		return null;
	}

	@Override
	Node find(String search, boolean wildcard) {
		if (getKeyGroup() != null && getKeyGroup().equalsIgnoreCase(search)) {
			return this;
		}
		for (Iterator<Node> iterator = nodeList.iterator(); iterator.hasNext();) {
			Node node = iterator.next();
			Node searchNode = node.find(search, wildcard);
			if (searchNode != null) {
				return searchNode;
			}
		}
		return null;
	}

	public List<Node> getNodeList() {
		return nodeList;
	}

	public String getLabel() {
		return label;
	}

	public void setLabel(String label) {
		this.label = label;
	}

	@Override
	String getNodeType() {
		return NODE_TYPE_COMPLEX;
	}

	@Override
	public void print() {
		int deep = 0;
		StringBuilder builder = new StringBuilder();
		String desc = this.label != null ? this.label : this.getKeyGroup() != null ? this.getKeyGroup() : "Root: ";
		builder.append(String.format("%s%n", desc));
		for (int i = 0; i < nodeList.size(); i++) {
			Node node = nodeList.get(i);
			builder.append(node.print(deep + 1));
		}
		System.out.println(builder.toString());
	}

	@Override
	protected String print(int deep) {
		StringBuilder builder = new StringBuilder();
		if (deep == 0) {
			String desc = this.label != null ? this.label : this.getKeyGroup() != null ? this.getKeyGroup() : "Root: ";
			builder.append(String.format("%s%n", desc));
		} else {
			String desc = this.label != null ? this.label
					: this.getKeyGroup() != null ? this.getKeyGroup() : "Level_" + deep;
			builder.append((String.format("%-" + deep + "s%s%n", " ", "[{1}]")).replace(" ", "=").replace("{1}", desc));
		}
		for (Iterator<Node> iterator = nodeList.iterator(); iterator.hasNext();) {
			Node node = iterator.next();
			builder.append(node.print(deep + 1));
		}
		return builder.toString();
	}

	@Override
	public Map<String, String> map(Map<String, String> map) {
		for (int i = 0; i < nodeList.size(); i++) {
			Node node = nodeList.get(i);
			node.map(map);
		}
		return map;
	}

	@Override
	public Map<String, String> map(Map<String, String> map, int deep, int limit) {
		if (deep < limit) {
			for (int i = 0; i < nodeList.size(); i++) {
				Node node = nodeList.get(i);
				node.map(map, deep + 1, limit);
			}
		}
		return map;
	}

}
