package com.sdtool.common.entity.system;

import com.sdtool.common.entity.base.BaseEntity;
import com.sweetfish.util.Comment;
import org.rex.db.RColumn;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * Created by jlutt on 2018-07-12.
 *
 * @author jlutt
 */
public class Menu extends BaseEntity {

    @Comment("")
    @RColumn("id")
    private int id;

    @Comment("菜单名称")
    @RColumn("menuname")
    private String menuName;

    @Comment("父级菜单ID")
    @RColumn("parentid")
    private long parentId;

    @Comment("排序")
    @RColumn("sortnum")
    private int sortNum;

    /**
     * 菜单URL
     */
    @Comment("菜单URL")
    @RColumn("url")
    private String url;

    /**
     * 类型:M目录,C菜单,F按钮
     */
    @Comment("菜单类型")
    @RColumn("menutype")
    private String menuType;

    /**
     * 菜单状态:0显示,1隐藏
     */
    @Comment("菜单状态")
    @RColumn("visible")
    private int visible;

    @Comment("是否缓存")
    @RColumn("cacheflag")
    private int cacheFlag;

    /**
     * 权限字符串
     */
    @Comment("权限字符")
    @RColumn("perms")
    private String perms;

    /**
     * 菜单图标
     */
    @Comment("菜单图标")
    @RColumn("icon")
    private String icon;

    @Comment("备注")
    @RColumn("remark")
    private String remark;

    @Comment("父级菜单")
    @RColumn("parentname")
    private String parentName;

    @Comment("组件名称")
    @RColumn("pathname")
    private String pathName;

    @Comment("路由名称")
    @RColumn("route")
    private String route;

    @Comment("运行方式0网页 1delphi界面")
    @RColumn("runkind")
    private int runKind;

    @Comment("BPL包名")
    @RColumn("delphipackage")
    private String delphiPackage;

    @Comment("运行方式Method和Form")
    @RColumn("delphirunkind")
    private String delphiRunKind;

    @Comment("运行窗体类名/方法名")
    @RColumn("delphirunform")
    private String delphiRunForm;

    @Comment("窗体显示方式 Show和ShowModal")
    @RColumn("delphiformshow")
    private String delphiFormShow;

    @Comment("BPL参数，按照 Method/Form:Show/ShowModal:FormClass@Form参数 格式")
    @RColumn("delphiparams")
    private String delphiParams;

    /**
     * 子菜单，对于菜单和按钮不允许有子级菜单，只有目录能有子级菜单
     */
    @Comment("子菜单列表")
    private List<Menu> children = new ArrayList<>();

    public int getId() {
        return id;
    }

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

    public String getMenuName() {
        return menuName;
    }

    public void setMenuName(String menuName) {
        this.menuName = menuName;
    }

    public long getParentId() {
        return parentId;
    }

    public void setParentId(long parentId) {
        this.parentId = parentId;
    }

    public String getUrl() {
        return url;
    }

    public void setUrl(String url) {
        this.url = url;
    }

    public String getMenuType() {
        return menuType;
    }

    public void setMenuType(String menuType) {
        this.menuType = menuType;
    }

    public int getVisible() {
        return visible;
    }

    public void setVisible(int visible) {
        this.visible = visible;
    }

    public String getPerms() {
        return perms;
    }

    public void setPerms(String perms) {
        this.perms = perms;
    }

    public String getIcon() {
        return icon;
    }

    public void setIcon(String icon) {
        this.icon = icon;
    }

    public String getRemark() {
        return remark;
    }

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

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

    public void setChildren(List<Menu> children) {
        this.children = children;
    }

    public int getSortNum() {
        return sortNum;
    }

    public void setSortNum(int sortNum) {
        this.sortNum = sortNum;
    }

    public String getParentName() {
        return parentName;
    }

    public void setParentName(String parentName) {
        this.parentName = parentName;
    }

    public String getRoute() {
        return route;
    }

    public void setRoute(String route) {
        this.route = route;
    }

    public int getRunKind() {
        return runKind;
    }

    public void setRunKind(int runKind) {
        this.runKind = runKind;
    }

    public String getDelphiPackage() {
        return delphiPackage;
    }

    public void setDelphiPackage(String delphiPackage) {
        this.delphiPackage = delphiPackage;
    }

    public String getDelphiParams() {
        return delphiParams;
    }

    public void setDelphiParams(String delphiParams) {
        this.delphiParams = delphiParams;
    }

    public String getDelphiRunKind() {
        return delphiRunKind;
    }

    public void setDelphiRunKind(String delphiRunKind) {
        this.delphiRunKind = delphiRunKind;
    }

    public String getDelphiRunForm() {
        return delphiRunForm;
    }

    public void setDelphiRunForm(String delphiRunForm) {
        this.delphiRunForm = delphiRunForm;
    }

    public String getDelphiFormShow() {
        return delphiFormShow;
    }

    public void setDelphiFormShow(String delphiFormShow) {
        this.delphiFormShow = delphiFormShow;
    }

    public int getCacheFlag() {
        return cacheFlag;
    }

    public void setCacheFlag(int cacheFlag) {
        this.cacheFlag = cacheFlag;
    }

    public String getPathName() {
        return pathName;
    }

    public void setPathName(String pathName) {
        this.pathName = pathName;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) {
            return true;
        }
        if (o == null || getClass() != o.getClass()) {
            return false;
        }
        Menu menu = (Menu) o;
        return id == menu.id;
    }

    @Override
    public int hashCode() {

        return Objects.hash(id);
    }

    private Stream<Menu> flattenStream() {
        return Stream.concat(
                Stream.of(this),
                children.stream().flatMap(Menu::flattenStream)
        );
    }

    public static List<Menu> flattenList(Menu root) {
        return root.flattenStream().collect(Collectors.toList());
    }
}
