package com.persagy.adm.diagram.manage;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.persagy.adm.diagram.core.ContentParser;
import com.persagy.adm.diagram.core.DataStrategy;
import com.persagy.adm.diagram.core.DiagramDataLoader;
import com.persagy.adm.diagram.core.model.Diagram;
import com.persagy.adm.diagram.core.model.logic.CalcContext;
import com.persagy.adm.diagram.core.util.MyObjectMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;

import java.util.Map;

/**
 * 系统图的相关操作
 * @author zhaoyk
 */
@Service
public class DiagramManager {

	private final DataStrategy dataStrategy;

	@Autowired
	private ContentParser parser;

	@Autowired
	private MyObjectMapper myObjectMapper;

	@Autowired
	public DiagramManager(@Qualifier(DataStrategy.IMPL_QUALIFIER) DataStrategy dataStrategy) {
		this.dataStrategy = dataStrategy;
	}

	/**
	 * 对系统图进行初始化构建操作
	 * @param autoLayout 是否自动执行布局计算
	 */
	public void buildDiagram(Diagram diagram, boolean autoLayout){
		autoLayout = autoLayout && diagram.getTemplate() == null;

		if(diagram.getTemplate() == null){
			loadTemplate(diagram);
		}

		diagram.init();
		new DiagramDataLoader(diagram, dataStrategy).initLoad();

		if(autoLayout) {
			diagram.layout(new CalcContext(diagram));
		}
	}

	/**
	 * 对系统图进行初始化构建操作，并根据需要自动执行布局计算
	 */
	public void buildDiagram(Diagram diagram){
		buildDiagram(diagram, true);
	}

	private void loadTemplate(Diagram diagram){
		if (diagram.getTemplateId() != null) {
			diagram.setTemplate(dataStrategy.getTemplate(diagram.getTemplateId()));
		}
	}

	/**
	 * 重置diagram
	 */
	public void resetDiagram(Diagram diagram) {
		diagram.setTemplate(null);
		diagram.getLines().clear();
		diagram.getNodes().clear();
	}

	/**
	 * 系统图自动布局计算
	 */
	public void layout(Diagram diagram) {
		diagram.clearLayout();
		diagram.layout(new CalcContext(diagram));
	}

	/**
	 * 自动加载数据（设备、关系）
	 */
	public Diagram loadData(Diagram diagram){
		buildDiagram(diagram, false);

		CalcContext context = new CalcContext(diagram);
		new DiagramDataLoader(diagram, dataStrategy).autoLoad(context);

		diagram.layout(context);

		return diagram;
	}

	/**
	 * 给显示层的json数据
	 */
	public String json4View(Object data){
		try{
			return myObjectMapper.mapper4View().writeValueAsString(data);
		}catch (JsonProcessingException e){
			throw new RuntimeException(e);
		}
	}

	/**
	 * 给编辑层的json数据
	 */
	public String json4Edit(Object data){
		try{
			return myObjectMapper.mapper4Edit().writeValueAsString(data);
		}catch (JsonProcessingException e){
			throw new RuntimeException(e);
		}
	}

	/**
	 * 解析Map格式的数据(来自web端编辑器)，转换为Diagram对象
	 */
	public Diagram fromMapData(Map<String, Object> map){
		return parser.parseContent(parser.toJson(map), Diagram.class);
	}

}
