/* 
-*- coding: latin-1 -*-

This file is part of RefactorErl.

RefactorErl is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published
by the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

RefactorErl is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License
along with RefactorErl.  If not, see <http://plc.inf.elte.hu/erlang/>.

The Original Code is RefactorErl.

The Initial Developer of the Original Code is Eötvös Loránd University.
Portions created  by Eötvös Loránd University and ELTE-Soft Ltd.
are Copyright 2007-2025 Eötvös Loránd University, ELTE-Soft Ltd.
and Ericsson Hungary. All Rights Reserved.
*/

package com.refactorerl.ui.logic.investigations;

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

import com.ericsson.otp.erlang.OtpErlangObject;
import com.ericsson.otp.erlang.OtpErlangPid;
import com.refactorerl.ui.common.Pair;

public class InvestigationNode implements Cloneable {
	// note: pid is "<"+ node() +"."+ id() +"."+ serial() +">"
	final public OtpErlangPid pid;

	public OtpErlangPid parentPid;

	public List<OtpErlangPid> childPids;

	public InvestigationNode parent = null; // not set in constructor

	public List<InvestigationNode> children = new ArrayList<>(); // not set in
																	// constructor

	public String name;
	public boolean shown;
	public boolean memo;
	public OtpErlangObject graphNode;
	public String text;
	public String label;

	public String filePath;
	public int offset;
	public Pair<Integer, Integer> textPosition;
	public int lineNum;
	public String fileItemLabel;
	public Pair<Integer, Integer> screenPosition;

	public InvestigationNode(OtpErlangPid pid, OtpErlangPid parentPid,
			List<OtpErlangPid> childPids, String name, boolean shown,
			boolean memo, OtpErlangObject graphNode, String text, String label,
			String filePath, int offset, Pair<Integer, Integer> textPosition,
			int lineNum, String fileItemLabel,
			Pair<Integer, Integer> screenPosition) {
		super();
		this.pid = pid;
		this.parentPid = parentPid;
		this.childPids = childPids;
		this.name = name;
		this.shown = shown;
		this.memo = memo;
		this.graphNode = graphNode;
		this.text = text;
		this.label = label;
		this.filePath = filePath;
		this.offset = offset;
		this.textPosition = textPosition;
		this.lineNum = lineNum;
		this.fileItemLabel = fileItemLabel;
		this.screenPosition = screenPosition;
	}

	/** Shallow copy */
	protected InvestigationNode(InvestigationNode node) {
		super();
		this.pid = node.pid;
		this.parentPid = node.parentPid;
		this.childPids = node.childPids;
		this.name = node.name;
		this.shown = node.shown;
		this.memo = node.memo;
		this.graphNode = node.graphNode;
		this.text = node.text;
		this.label = node.label;
		this.filePath = node.filePath;
		this.offset = node.offset;
		this.textPosition = node.textPosition;
		this.lineNum = node.lineNum;
		this.fileItemLabel = node.fileItemLabel;
		this.screenPosition = node.screenPosition;
	}

	public void addChild(InvestigationNode child) {
		children.add(child);
	}

	public void removeChild(InvestigationNode child) {
		children.remove(child);
	}

	protected OtpErlangPid getPid() {
		return pid;
	}

	protected OtpErlangPid getParentPid() {
		return parentPid;
	}

	protected List<OtpErlangPid> getChildPids() {
		return childPids;
	}

	public InvestigationNode getParent() {
		return parent;
	}

	public void setParent(InvestigationNode parent) {
		this.parent = parent;
	}

	public List<InvestigationNode> getChildren() {
		return children;
	}

	@Override
	public Object clone() throws CloneNotSupportedException {
		InvestigationNode clone = new InvestigationNode(pid, parentPid,
				childPids, name, shown, memo, graphNode, text, label, filePath,
				offset, textPosition, lineNum, fileItemLabel, screenPosition);

		clone.setParent(parent);
		for (InvestigationNode node : children) {
			clone.addChild(node);
		}

		return clone;
	}

	/** Will not include parent and children */
	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result
				+ ((childPids == null) ? 0 : childPids.hashCode());
		result = prime * result
				+ ((fileItemLabel == null) ? 0 : fileItemLabel.hashCode());
		result = prime * result
				+ ((filePath == null) ? 0 : filePath.hashCode());
		result = prime * result
				+ ((graphNode == null) ? 0 : graphNode.hashCode());
		result = prime * result + ((label == null) ? 0 : label.hashCode());
		result = prime * result + lineNum;
		result = prime * result + (memo ? 1231 : 1237);
		result = prime * result + ((name == null) ? 0 : name.hashCode());
		result = prime * result + offset;
		result = prime * result
				+ ((parentPid == null) ? 0 : parentPid.hashCode());
		result = prime * result + ((pid == null) ? 0 : pid.hashCode());
		result = prime * result
				+ ((screenPosition == null) ? 0 : screenPosition.hashCode());
		result = prime * result + (shown ? 1231 : 1237);
		result = prime * result + ((text == null) ? 0 : text.hashCode());
		result = prime * result
				+ ((textPosition == null) ? 0 : textPosition.hashCode());
		return result;
	}

	/** Will not check equality for parent and children */
	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		InvestigationNode other = (InvestigationNode) obj;
		if (childPids == null) {
			if (other.childPids != null)
				return false;
		} else if (!childPids.equals(other.childPids))
			return false;
		if (fileItemLabel == null) {
			if (other.fileItemLabel != null)
				return false;
		} else if (!fileItemLabel.equals(other.fileItemLabel))
			return false;
		if (filePath == null) {
			if (other.filePath != null)
				return false;
		} else if (!filePath.equals(other.filePath))
			return false;
		if (graphNode == null) {
			if (other.graphNode != null)
				return false;
		} else if (!graphNode.equals(other.graphNode))
			return false;
		if (label == null) {
			if (other.label != null)
				return false;
		} else if (!label.equals(other.label))
			return false;
		if (lineNum != other.lineNum)
			return false;
		if (memo != other.memo)
			return false;
		if (name == null) {
			if (other.name != null)
				return false;
		} else if (!name.equals(other.name))
			return false;
		if (offset != other.offset)
			return false;
		if (parentPid == null) {
			if (other.parentPid != null)
				return false;
		} else if (!parentPid.equals(other.parentPid))
			return false;
		if (pid == null) {
			if (other.pid != null)
				return false;
		} else if (!pid.equals(other.pid))
			return false;
		if (screenPosition == null) {
			if (other.screenPosition != null)
				return false;
		} else if (!screenPosition.equals(other.screenPosition))
			return false;
		if (shown != other.shown)
			return false;
		if (text == null) {
			if (other.text != null)
				return false;
		} else if (!text.equals(other.text))
			return false;
		if (textPosition == null) {
			if (other.textPosition != null)
				return false;
		} else if (!textPosition.equals(other.textPosition))
			return false;
		return true;
	}

	@Override
	public String toString() {
		return "InvestigationNode [name=" + name + ", pid=" + pid //$NON-NLS-1$ //$NON-NLS-2$
				+ ", parentPid=" + parentPid + ", childPids=" + childPids //$NON-NLS-1$ //$NON-NLS-2$
				+ ", shown=" + shown + ", memo=" + memo + ", graphNode=" //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
				+ graphNode + ", text=" + text + ", label=" + label //$NON-NLS-1$ //$NON-NLS-2$
				+ ", filePath=" + filePath + ", offset=" + offset //$NON-NLS-1$ //$NON-NLS-2$
				+ ", textPosition=" + textPosition + ", lineNum=" + lineNum //$NON-NLS-1$ //$NON-NLS-2$
				+ ", fileItemLabel=" + fileItemLabel + ", screenPosition=" //$NON-NLS-1$ //$NON-NLS-2$
				+ screenPosition + "]"; //$NON-NLS-1$
	}

}
