package com.miya.weighing;

import android.content.Context;
import android.support.annotation.NonNull;
import android.util.Log;

import com.miya.weighing.utils.D;

public class WeighingManager {

    final static String TAG = WeighingManager.class.getSimpleName();

    /**
     * 设备类型枚举，用于轮询过程中的反射
     */
    enum Type {
        TYPE_HISENSE("hisense", HisenseWeighing.class.getName()),
        TYPE_YINGTAI("yingtai", YingtaiWeighing.class.getName()),
        TYPE_SUNMI("shangmi", SunmiWeighing.class.getName()),
        TYPE_CHUANGJIE("chuangjie", ChuangjieWeighing.class.getName());
        //这里添加扩展的驱动

        /**
         * 设备类型名称
         */
        String typeName;

        /**
         * 设备驱动类全类名
         */
        String clsName;

        Type(String typeName, String clsName) {
            this.typeName = typeName;
            this.clsName = clsName;
        }

        @Override
        public String toString() {
            return "Type{" +
                    "typeName='" + typeName + '\'' +
                    ", clsName='" + clsName + '\'' +
                    '}';
        }
    }

    /**
     * 标准称重接口
     */
    Weighing weighing;

    /**
     * 单例
     */
    private static WeighingManager instance;

    /**
     * 单例模式
     *
     * @return
     */
    public static WeighingManager getInstance() {
        synchronized (WeighingManager.class) {
            if (instance == null) {
                instance = new WeighingManager();
            }
            return instance;
        }
    }

    private WeighingManager() {
    }

    /**
     * 同步轮询初始化，外部无需关心重量管理者用的到底是哪个称重硬件
     *
     * @param context
     * @return
     */
    public boolean init(@NonNull Context context) {
        boolean result = false;
        //轮询所有的称重服务,注意是同步方法
        for (Type type : Type.values()) {
            //确保之前的称重实例已被销毁
            try {
                if (weighing != null) {
                    weighing.release();
                }
                //反射新建实例
                Class weighingClass = Class.forName(type.clsName);
                weighing = (Weighing) weighingClass.newInstance();
                result = weighing.init(context);
                if (result == true) {
                    //初始化成功
                    weighing.setWeighingName(type.typeName);
                    Log.i(TAG, "称重硬件初始化成功==>" + weighing.getWeighingName());
                    return true;
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        if (result == false) {
            //没有找到称重硬件，先销毁，再返回false
            if (weighing != null) {
                weighing.release();
            }
            weighing = null;
            Log.i(TAG, "称重硬件初始化失败，没有找到对应的硬件");
            return false;
        }
        return false;
    }

    /**
     * 获取当前称重硬件组件
     *
     * @return 当前正在使用的称重硬件
     */
    public Weighing getWeighing() {
        return weighing;
    }

    /**
     * 供外部检测是否已经连接上对应的驱动
     *
     * @return true：正常工作中；false：没有对应的驱动
     */
    public boolean isConnected() {
        return weighing != null;
    }

    /**
     * 保险起见提供指定硬件的初始化
     * ps:谨慎调用
     *
     * @param context
     * @param type    指定硬件类型
     * @return
     */
    public boolean init(Context context, Type type) {
        if (type == null) {
            return false;
        }
        //是否支持指定硬件
        boolean isSupported = false;
        for (Type tmpType : Type.values()) {
            if (type.typeName.equals(tmpType.typeName)) {
                isSupported = true;
            }
        }
        if (isSupported == false) {
            return false;
        }
        //反射新建实例
        try {
            Class weighingClass = Class.forName(type.clsName);
            weighing = (Weighing) weighingClass.newInstance();
            boolean result = weighing.init(context);
            if (result == true) {
                weighing.setWeighingName(type.clsName);
                D.i(TAG, "称重硬件初始化成功==>" + weighing.getWeighingName());
            }
            return result;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }
}
