/*
 * Copyright (C) 2015 AlexMofer
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.gingersoft.gsa.cloud.print;

import android.bluetooth.BluetoothDevice;
import android.os.AsyncTask;

import com.elvishew.xlog.XLog;
import com.gingersoft.gsa.cloud.common.logan.LoganManager;
import com.gingersoft.gsa.cloud.database.bean.PrinterDeviceBean;

import java.util.List;

/**
 * 打印执行者
 * Created by Alex on 2016/11/10.
 */
public class PrintExecutor {
    protected final String TAG = this.getClass().getSimpleName();
    private PrintSocketHolder holder;
    private int mReconnectTimes = 0;
    private int time = 0;
    private String prjIds;
    private PrintSocketHolder.OnStateChangedListener listener;
    private OnPrintResultListener mListener;
    private OnPrjPrintResultListener onPrjPrintResultListener;

    public PrintExecutor(BluetoothDevice device) {
        holder = new PrintSocketHolder(device);
    }

    public PrintExecutor(PrinterDeviceBean printerDeviceBean) {
        holder = new PrintSocketHolder(printerDeviceBean);
    }

    public void setPrinterDeviceBean(PrinterDeviceBean printerDeviceBean) {
        if (holder != null) {
            holder.setPrinterDeviceBean(printerDeviceBean);
        }
    }

    /**
     * 执行打印请求
     *
     * @return 错误代码
     */
    private int doRequest(PrintDataMaker maker) {
        if (mReconnectTimes == 0) {
            holder.onPrinterStateChanged(PrintSocketHolder.STATE_0);
            List<byte[]> data = maker.getPrintData();
            prjIds = maker.getPrjIds();
            if (!holder.isSocketPrepared()) {
                int prepare = holder.prepareSocket();
                if (prepare != PrintSocketHolder.ERROR_0) {
                    return prepare;
                }
            }
            LoganManager.w_printer(TAG,"PrintTask doRequest  holder.sendData(data) ------------------------------->");
            return holder.sendData(data);
        } else {
            holder.onPrinterStateChanged(PrintSocketHolder.STATE_0);
            List<byte[]> data = maker.getPrintData();
            prjIds = maker.getPrjIds();
            if (holder.isSocketPrepared()) {
                LoganManager.w_printer(TAG,"PrintTask doRequest  sendData(data) --------------连接打印机完成----------------->");
                if (sendData(data)) {
                    LoganManager.w_printer(TAG,"PrintTask doRequest  sendData(data) -------------打印成功------------------>");
                    return PrintSocketHolder.ERROR_0;
                } else {
                    LoganManager.w_printer(TAG,"PrintTask doRequest  sendData(data) -------------打印失败------------------>");
                    return PrintSocketHolder.ERROR_100;
                }
            } else {
                if (prepareSocket() && sendData(data)) {
                    LoganManager.w_printer(TAG,"PrintTask doRequest  sendData(data) -------------打印成功------------------>");
                    return PrintSocketHolder.ERROR_0;
                } else {
                    LoganManager.w_printer(TAG,"PrintTask doRequest  sendData(data) -------------打印失败------------------>");
                    return PrintSocketHolder.ERROR_100;
                }
            }
        }
    }

    /**
     * 执行打印请求
     *
     * @return 错误代码
     */
    public int doPrinterRequest(PrintDataMaker maker) {
        holder.setOnStateChangedListener(listener);
        return doRequest(maker);
    }

    private boolean prepareSocket() {
        time++;
        boolean prepareSocket = time < mReconnectTimes &&
                (holder.prepareSocket() == PrintSocketHolder.ERROR_0 || prepareSocket());
        return prepareSocket;
    }

    private boolean sendData(List<byte[]> data) {
        if (holder.sendData(data) == PrintSocketHolder.ERROR_0) {
            time = 0;
            return true;
        } else {
            return prepareSocket() && sendData(data);
        }
    }

    /**
     * 异步执行打印请求
     */
    public void doPrinterRequestAsync(PrintDataMaker maker) {
        new PrintTask().execute(maker);
    }

    /**
     * 销毁
     */
    public int closeSocket() {
        return holder.closeSocket();
    }

    /**
     * 设置IP及端口
     */
    public void setIp(PrinterDeviceBean printerDeviceBean) {
        holder.setIp(printerDeviceBean);
    }

    /**
     * 设置蓝牙
     *
     * @param device 设备
     */
    public void setDevice(BluetoothDevice device) {
        holder.setDevice(device);
    }

    /**
     * 设置状态监听
     *
     * @param listener 监听
     */
    public void setOnStateChangedListener(PrintSocketHolder.OnStateChangedListener listener) {
        this.listener = listener;
    }

    /**
     * 设置重连次数
     *
     * @param times 次数
     */
    public void setReconnectTimes(int times) {
        mReconnectTimes = times;
    }

    /**
     * 设置结果回调
     *
     * @param listener 回调
     */
    public void setOnPrintResultListener(OnPrintResultListener listener) {
        this.mListener = listener;
    }

    public interface OnPrintResultListener {
        void onResult(int errorCode, PrinterDeviceBean printerDeviceBean);
    }

    /**
     * PRJ打印結果回調
     */
    public interface OnPrjPrintResultListener {
        void onResult(int errorCode, String ids);
    }

    public void setOnPrjPrintResultListener(OnPrjPrintResultListener onPrjPrintResultListener) {
        this.onPrjPrintResultListener = onPrjPrintResultListener;
    }

    private class PrintTask extends AsyncTask<PrintDataMaker, Integer, Integer> implements
            PrintSocketHolder.OnStateChangedListener {

        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            LoganManager.w_printer(TAG,"PrintTask onPreExecute");
            holder.setOnStateChangedListener(this);
        }

        @Override
        protected Integer doInBackground(PrintDataMaker... makers) {
            LoganManager.w_printer(TAG,"PrintTask doInBackground  makers.length：" + makers.length);
            if (makers == null || makers.length < 1) {
                return PrintSocketHolder.ERROR_0;
            }
            return doRequest(makers[0]);
        }

        @Override
        protected void onProgressUpdate(Integer... values) {
            super.onProgressUpdate(values);
            LoganManager.w_printer(TAG,"PrintTask onProgressUpdate  values：" + values);
            if (values == null || values.length < 1) {
                return;
            }
            if (listener != null) {
                listener.onStateChanged(values[0], holder.getPrinterDeviceBean());
            }
        }

        @Override
        protected void onPostExecute(Integer integer) {
            super.onPostExecute(integer);
            LoganManager.w_printer(TAG,"PrintTask onPostExecute  values：" + integer);
            if (integer != null) {
                onResult(integer);
            }
        }

        /**
         * 打印结果
         *
         * @param errorCode 错误代码
         */
        private void onResult(int errorCode) {
            try {
                LoganManager.w_printer(TAG,"PrintTask onResult  errorCode：" + errorCode);
                if (mListener != null)
                    mListener.onResult(errorCode, holder.getPrinterDeviceBean());
                if (onPrjPrintResultListener != null) {
                    onPrjPrintResultListener.onResult(errorCode, prjIds);
                }
            } catch (Exception e) {
                e.printStackTrace();
                LoganManager.w_printer(TAG,"PrintTask onResult  Exception：" + e.getMessage());
            }
        }

        @Override
        public void onStateChanged(int state, PrinterDeviceBean printerDeviceBean) {
            LoganManager.w_printer(TAG,"PrintTaskonStateChanged state: " + state);
            publishProgress(state);
        }
    }

}
