package risk.messagetool;

import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.TreeNode;
import javax.swing.tree.MutableTreeNode;
import java.util.Locale;
import java.util.HashMap;
import java.util.Collections;
import java.util.Comparator;

public class MyNode extends DefaultMutableTreeNode {

	private boolean hasmessage;
	private HashMap map;

	private boolean haschildren;
	private boolean needchildren;

	// used when getting nodes from the plugin
	public MyNode(String name, boolean hasm, boolean hasch) {

		super(name);

		hasmessage = hasm;

		haschildren = hasch;

		setup();

	}

	// used when adding new nodes
	protected MyNode(String name, boolean a) {

		super(name);

		if (a) {
			hasmessage = true;
			map = new HashMap();
		}
		else {

			haschildren = true;

		}
	}

	private void setup() {


		if (haschildren && isLeaf() ) {

			add( new MyNode(null,false,false) );
			needchildren = true;
		}

		if (hasmessage && map==null) {

			map = new HashMap();

		}


	}

	public void removeAllChildren() {

		if (haschildren) {

			super.removeAllChildren();
			setup();

		}

	}

	public void add(MutableTreeNode newChild) {

		if (this.children!=null && this.children.contains(newChild)) { return; }

		super.add(newChild);
		Collections.sort(this.children,MessageTool.CASE_INSENSITIVE_ORDER);

	}

	public void setHasChildren(boolean b) { // only used for true for now

		haschildren = b;

	}

	public void setHasMessage(boolean b) { // only used for true for now

		hasmessage = b;
		setup();

	}

	public boolean hasMessage() {

		return hasmessage;

	}

	public boolean hasChildren() {

		return haschildren;

	}

	public String reload(Mtcomm mycomm, Locale l) throws Exception {

		String m = mycomm.getMessage(this,l);
		map.put(l,m);

		return m;

	}

	public String getMessage(Mtcomm mycomm, Locale l) throws Exception {

		if (map.containsKey(l)) {

			return (String)map.get(l);

		}
		else {

			return reload(mycomm,l);
		}

	}

	public void saveMessage(Mtcomm mycomm, Locale l,String m) throws Exception {

		mycomm.saveMessage(this,l,m);

		map.put(l,m);

	}

	public void loadChildren(Mtcomm mycomm) throws Exception {

		if (needchildren) {

			needchildren = false;

			//super.removeAllChildren();
			remove(0);

			mycomm.addChildren(this);
		}
	}


	public String getName() {

		TreeNode[] path = getPath();

		StringBuffer buffer = new StringBuffer();

		for (int c=1; c<path.length;c++) {

			buffer.append(path[c]);
			if (c<path.length-1) { buffer.append("."); }

		}

		return buffer.toString();

	}

	public MyNode getChild(String s) {

		if ( isLeaf() ) { return null; }

		int a = Collections.binarySearch(this.children, s, MessageTool.CASE_INSENSITIVE_ORDER);

		if (a<0) { return null; }

		return (MyNode)this.children.elementAt(a);

	}

	// this is used to update during the search if things do match

	public boolean equals(Object o) {

		MyNode no = (MyNode)o;

		if (getUserObject().equals(no.getUserObject())) {

			if ( hasMessage() && !no.hasMessage() ) {

				no.hasmessage = true;
				no.setup();

			}
			else if ( !hasMessage() && no.hasMessage() ) {

				hasmessage = true;
				setup();

			}

			if ( hasChildren() && !no.hasChildren() ) {

				no.haschildren = true;
				no.setup();

			}
			else if ( !hasChildren() && no.hasChildren() ) {

				haschildren = true;
				setup();

			}
			return true;
		}

		return false;
	}

}
