package cn.bunny.pattern14;

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

public class Composite {
    public static void main(String[] args) {
        ConcreteCompany company = new ConcreteCompany("总公司");

        // 总公司的分公司
        ConcreteCompany subCompany1 = new ConcreteCompany("上海分公司");
        subCompany1.add(new HRDepartment("上海华东分公司"));
        subCompany1.add(new FinanceDepartment("上海华东分公司"));
        company.add(subCompany1);

        // 总公司的分公司
        ConcreteCompany subCompany2 = new ConcreteCompany("北京分公司");
        subCompany2.add(new HRDepartment("北京华东分公司"));
        subCompany2.add(new FinanceDepartment("北京华东分公司"));
        company.add(subCompany2);

        // 上海的南京分公司
        ConcreteCompany subCompany3 = new ConcreteCompany("南京分公司");
        subCompany3.add(new HRDepartment("南京华东分公司"));
        subCompany3.add(new FinanceDepartment("南京华东分公司"));
        subCompany1.add(subCompany3);

        System.out.println("---------------------显示组织图---------------------");
        company.display(1);

        System.out.println("---------------------显示职责---------------------");
        company.duty();
    }

    // Component 抽象子组件
    abstract static class Company {
        protected String name;

        public Company(String name) {
            this.name = name;
        }

        /**
         * 添加节点
         *
         * @param company 子组件
         */
        public abstract void add(Company company);

        /**
         * 删除节点
         *
         * @param company 子组件
         */
        public abstract void remove(Company company);

        /**
         * 显示
         *
         * @param depth 深度
         */
        public abstract void display(int depth);

        /**
         * 职责
         */
        public abstract void duty();
    }

    // Composite 容器对象
    static class ConcreteCompany extends Company {

        private final List<Company> companyList = new ArrayList<>();

        public ConcreteCompany(String name) {
            super(name);
        }

        /**
         * 添加节点
         *
         * @param company 子组件
         */
        @Override
        public void add(Company company) {
            companyList.add(company);
        }

        /**
         * 删除节点
         *
         * @param company 子组件
         */
        @Override
        public void remove(Company company) {
            companyList.remove(company);
        }

        /**
         * 显示
         *
         * @param depth 深度
         */
        @Override
        public void display(int depth) {
            for (int i = 0; i < depth; i++) System.out.print("-");

            System.out.println(name);

            for (Company company : companyList) company.display(depth + 1);
        }

        /**
         * 职责
         */
        @Override
        public void duty() {
            for (Company company : companyList) company.duty();
        }
    }

    // Leaf（叶子节点）-人事部门
    static class HRDepartment extends Company {
        public HRDepartment(String name) {
            super(name);
        }

        /**
         * 添加节点
         *
         * @param company 子组件
         */
        @Override
        public void add(Company company) {
        }

        /**
         * 删除节点
         *
         * @param company 子组件
         */
        @Override
        public void remove(Company company) {
        }

        /**
         * 显示
         *
         * @param depth 深度
         */
        @Override
        public void display(int depth) {
            for (int i = 0; i < depth; i++) System.out.print("-");
            System.out.println(name);
        }

        /**
         * 职责
         */
        @Override
        public void duty() {
            System.out.println(name + "：员工招聘培训管理");
        }
    }

    // Leaf（叶子节点）-财务部
    static class FinanceDepartment extends Company {
        public FinanceDepartment(String name) {
            super(name);
        }

        /**
         * 添加节点
         *
         * @param company 子组件
         */
        @Override
        public void add(Company company) {
        }

        /**
         * 删除节点
         *
         * @param company 子组件
         */
        @Override
        public void remove(Company company) {
        }

        /**
         * 显示
         *
         * @param depth 深度
         */
        @Override
        public void display(int depth) {
            for (int i = 0; i < depth; i++) System.out.print("-");
            System.out.println(name);
        }

        /**
         * 职责
         */
        @Override
        public void duty() {
            System.out.println(name + "：公司财务收支管理");
        }
    }
}
