package com.persagy.adm.diagram.core.model.template;

import com.google.gson.annotations.Expose;
import com.persagy.adm.diagram.core.model.base.Container;
import com.persagy.adm.diagram.core.model.base.IComponent;
import com.persagy.adm.diagram.core.model.base.Layout;
import com.persagy.adm.diagram.core.model.base.XY;

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

/**
 * 系统图模板
 * @author zhaoyk
 */
public class DiagramTemplate {

	public static final String FRAME_ID = "frame";

	/**
	 * 模板对应的系统图类型代码
	 */
	@Expose(serialize = false)
	private String diagramType;

	/**
	 * 模板id
	 */
	@Expose(serialize = false)
	private String id;

	/**
	 * 模板名称
	 */
	@Expose(serialize = false)
	private String name;

	/**
	 * 模板编码
	 */
	@Expose(serialize = false)
	private String code;

	/**
	 * 描述信息
	 */
	@Expose(serialize = false)
	private String remark;

	/**
	 * 模板容器框架
	 */
	@Expose
	private Container frame;

	/**
	 * 自由定位容器列表
	 */
	@Expose
	private List<Container> scatteredContainers;

	/**
	 * 预定义的干管/线
	 */
	@Expose
	private List<MainPipe> mainPipes;

	public String getDiagramType() {
		return diagramType;
	}

	public void setDiagramType(String diagramType) {
		this.diagramType = diagramType;
	}

	public String getId() {
		return id;
	}

	public void setId(String id) {
		this.id = id;
	}

	public String getName() {
		return name;
	}

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

	public String getCode() {
		return code;
	}

	public void setCode(String code) {
		this.code = code;
	}

	public String getRemark() {
		return remark;
	}

	public void setRemark(String remark) {
		this.remark = remark;
	}

	public Container getFrame() {
		return frame;
	}

	public void setFrame(Container frame) {
		this.frame = frame;
	}

	public List<Container> getScatteredContainers() {
		return scatteredContainers;
	}

	public void setScatteredContainers(List<Container> scatteredContainers) {
		this.scatteredContainers = scatteredContainers;
	}

	public List<MainPipe> getMainPipes() {
		return mainPipes;
	}

	public void setMainPipes(List<MainPipe> mainPipes) {
		this.mainPipes = mainPipes;
	}

	public void init() {
		frame.initParent();
		initScattered(frame);
	}

	private void initScattered(Container con){
		//框架中的自由定位容器移动到列表中
		if(con.getChildren() != null) {
			for (int i = 0; i < con.getChildren().size(); i++) {
				IComponent comp = con.getChildren().get(i);
				if (comp instanceof Container) {
					Container subCon = (Container)comp;
					if(subCon.isAbsolutePosition()){
						if(scatteredContainers == null) {
							scatteredContainers = new ArrayList<>();
						}
						scatteredContainers.add(subCon);

						con.getChildren().remove(i);
						i--;
					}
					initScattered(subCon);
				}
			}
		}

		//列表里的非自由定位容器移动到框架跟容器下
		if (scatteredContainers != null) {
			Iterator<Container> iter = scatteredContainers.iterator();
			while (iter.hasNext()){
				Container c = iter.next();
				if(!c.isAbsolutePosition()){
					frame.addComp(c);
					iter.remove();
				}
			}
		}
	}

	public Container getContainerById(String containerId) {
		if(frame.getId().equals(containerId)) {
			return frame;
		}

		IComponent comp = frame.findComponent(containerId);
		if(comp instanceof Container) {
			return (Container)comp;
		}

		if (scatteredContainers != null) {
			for(Container con : scatteredContainers){
				if(con.getId().equals(containerId)) {
					return con;
				}
			}
		}

		return null;
	}

	public MainPipe getMainPipeById(String mainPipeId) {
		if(mainPipes != null) {
			for (MainPipe mainPipe : mainPipes) {
				if (mainPipe.getId().equals(mainPipeId)) {
					return mainPipe;
				}
			}
		}
		return null;
	}

	public void layout(XY location) {
		frame.setLocation(location);
		frame.layout();

		if (scatteredContainers != null) {
			for(Container con : scatteredContainers){
				con.layout();
			}
		}

		if (mainPipes != null) {
			for(MainPipe mainPipe : mainPipes) {
				mainPipe.layout(this);
			}
		}
	}

	public List<Container> getContainers() {
		List<Container> list = new ArrayList<>();
		getContainers(frame, list);

		if(scatteredContainers != null) {
			list.addAll(scatteredContainers);
		}

		return list;
	}

	private void getContainers(Container con, List<Container> list){
		list.add(con);

		if(con.getChildren() != null) {
			for(IComponent comp : con.getChildren()) {
				if (comp instanceof Container) {
					getContainers((Container) comp, list);
				}
			}
		}
	}


	public static DiagramTemplate defaultTemplate() {
		DiagramTemplate template = new DiagramTemplate();

		Container frame = new Container();
		frame.setId(FRAME_ID);
		frame.setPosition(frame.defaultPosition());
		frame.setLayout(Layout.defaultLayout(Layout.ROW));
		template.setFrame(frame);

		return template;
	}

}
