package org.ansj.domain;

import org.ansj.util.MathUtil;
import org.nlpcn.commons.lang.util.StringUtil;

import java.io.Serializable;
import java.util.List;
import java.util.Map;

public class Term implements Serializable {
	/**
	 *
	 */
	private static final long serialVersionUID = 1L;
	// 当前词
	private String name;
	//
	private String realName;
	// 当前词的起始位置
	private int offe;
	// 词性列表
	private TermNatures termNatures = TermNatures.NULL;
	// 词性列表
	private AnsjItem item = AnsjItem.NULL;
	// 同一行内数据
	private Term next;
	// 分数
	private double score = 0;
	// 本身分数
	private double selfScore = 1;
	// 起始位置
	private Term from;
	// 到达位置
	private Term to;
	// 本身这个term的词性.需要在词性识别之后才会有值,默认是空
	private Nature nature = Nature.NULL;
	//是否是一个新词
	private boolean newWord;
	//同义词
	private List<String> synonyms;


	private List<Term> subTerm = null;

	public Term(String name, int offe, AnsjItem item) {
		super();
		this.name = name;
		this.offe = offe;
		this.item = item;
		if (item.termNatures != null) {
			this.termNatures = item.termNatures;
			if (termNatures.nature != null) {
				this.nature = termNatures.nature;
			}
		}
	}

	public Term(String name, int offe, TermNatures termNatures) {
		super();
		this.name = name;
		this.offe = offe;
		this.termNatures = termNatures;
		if (termNatures.nature != null) {
			this.nature = termNatures.nature;
		}
	}

	public Term(String name, int offe, String natureStr, int natureFreq) {
		super();
		this.name = name;
		this.offe = offe;
		TermNature termNature = new TermNature(natureStr, natureFreq);
		this.nature = termNature.nature;
		this.termNatures = new TermNatures(termNature);
	}

	// 可以到达的位置
	public int toValue() {
		return offe + name.length();
	}

	public int getOffe() {
		return offe;
	}

	public void setOffe(int offe) {
		this.offe = offe;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	/**
	 * 核心构建最优的路径
	 *
	 * @param from
	 * @param relationMap
	 */
	public void setPathScore(Term from, Map<String, Double> relationMap) {
		// 维特比进行最优路径的构建
		double score = MathUtil.compuScore(from, this, relationMap);
		if (this.from == null || this.score == 0 || this.score >= score) {
			this.setFromAndScore(from, score);
		}
	}

	/**
	 * 核心分数的最优的路径,越小越好
	 *
	 * @param from
	 */
	public void setPathSelfScore(Term from, boolean asc) {
		double score = this.selfScore + from.score;
		// 维特比进行最优路径的构建
		if (this.from == null) {
			this.setFromAndScore(from, score);
		} else {
			if ((this.score > score) == asc) {
				this.setFromAndScore(from, score);
			}

		}
	}

	private void setFromAndScore(Term from, double score) {
		this.from = from;
		this.score = score;
	}

	/**
	 * 进行term合并
	 *
	 * @param to
	 */
	public Term merage(Term to) {
		this.name = this.name + to.getName();
		if (StringUtil.isNotBlank(this.realName) && StringUtil.isNotBlank(to.getRealName())) {
			this.realName = this.realName + to.getRealName();
		}
		this.setTo(to.to);
		return this;
	}

	/**
	 * 进行term合并,能合并空白字符
	 *
	 * @param to
	 */
	public Term merageWithBlank(Term to) {
		this.name = this.name + to.getName();
		this.realName = this.realName + to.getRealName();
		this.setTo(to.to);
		return this;
	}

	/**
	 * 更新偏移量
	 *
	 * @param offe
	 */
	public void updateOffe(int offe) {
		this.offe += offe;
	}

	public Term next() {
		return next;
	}

	/**
	 * 返回他自己
	 *
	 * @param next 设置他的下一个
	 * @return
	 */
	public Term setNext(Term next) {
		this.next = next;
		return this;
	}

	public Term from() {
		return from;
	}

	public Term to() {
		return to;
	}

	public void setFrom(Term from) {
		this.from = from;
	}

	public void setTo(Term to) {
		this.to = to;
	}

	/**
	 * 获得这个term的所有词性
	 *
	 * @return
	 */
	public TermNatures termNatures() {
		return termNatures;
	}

	public void setNature(Nature nature) {
		this.nature = nature;
	}

	/**
	 * 获得这个词的词性.词性计算后才可生效
	 *
	 * @return
	 */
	public Nature natrue() {
		return nature;
	}

	public String getNatureStr() {
		return nature.natureStr;
	}

	@Override
	public String toString() {
		if ("null".equals(nature.natureStr)) {
			return this.getRealName();
		}
		return this.getRealName() + "/" + nature.natureStr;
	}

	/**
	 * 将term的所有分数置为0
	 */
	public void clearScore() {
		this.score = 0;
		this.selfScore = 0;
	}

	public void setSubTerm(List<Term> subTerm) {
		this.subTerm = subTerm;
	}

	public List<Term> getSubTerm() {
		return subTerm;
	}

	public String getRealName() {
		if (realName == null) {
			return name;
		}
		return realName;
	}

	public String getRealNameIfnull() {
		return realName;
	}

	public void setRealName(String realName) {
		this.realName = realName;
	}

	public double score() {
		return this.score;
	}

	public void score(double score) {
		this.score = score;
	}

	public double selfScore() {
		return this.selfScore;
	}

	public void selfScore(double selfScore) {
		this.selfScore = selfScore;
	}

	public AnsjItem item() {
		return this.item;
	}

	public boolean isNewWord() {
		return newWord;
	}

	public void setNewWord(boolean newWord) {
		this.newWord = newWord;
	}

	public void updateTermNaturesAndNature(TermNatures termNatures) {
		this.termNatures = termNatures;
		this.nature = termNatures.nature;
	}

	public List<String> getSynonyms() {
		return synonyms;
	}

	public void setSynonyms(List<String> synonyms) {
		this.synonyms = synonyms;
	}

}
