package com.xixun.display;

import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.ServiceConnection;
import android.net.Uri;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.os.RemoteException;
import android.support.annotation.Nullable;
import android.util.Log;

import com.xixun.communicate.ClientsManage;
import com.xixun.communicate.Define;
import com.xixun.communicate.LedCardCommunication;
import com.xixun.communicate.MooncellFpga;
import com.xixun.communicate.TcpCommunication;
import com.xixun.communicate.WorkParams;
import com.xixun.joey.uart.IUartService;
import com.xixun.util.PlayerInfo;

import java.io.ByteArrayOutputStream;
import java.io.Closeable;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import static java.lang.Thread.sleep;

public class MyService extends Service {
    public static boolean bDisplay_RailWay=false;
    static int brightness;
    static boolean manual;

    public PlayerInfo playerInfo=null;
    public boolean bUseSerialPort=false;
    ClientsManage clientsManage=null;
    public LedCardCommunication ledCardCommunication = null;
    public WorkParams workParams=null;
    public String strStoragePath=null;
    BreakpointReceiver fw_receiver;
    BroadcastReceiver receiver_brightness;
    public Handler handlerRefreshDisplay=null;
    Boolean bNeedExit=false;
    public IUartService serialPorts=null;
    private boolean isBound_IUartService = false;                         // add byfw  2019/1/30
    private boolean isBound_PlayerInfo   = false;                         // add byfw  2019/1/30

    public MyService() {
    }
    /*@Override
    public IBinder onBind(Intent intent) {
        // TODO: Return the communication channel to the service.
        throw new UnsupportedOperationException("Not yet implemented");
    }*/

    @Override
    public IBinder onBind(Intent intent)
    {
        return new MyBinder();
    }

    class MyBinder extends MyAidl.Stub
    {
        /*
      设置屏幕亮度
       */
        @Override
        public boolean setBrightness(boolean manual, int brightness) throws RemoteException
        {
            MyLog.i("setBrightness............"+brightness);
            if (ledCardCommunication == null){
                ledCardCommunication = clientsManage.ledCardCommunication;
            }

            //update start定制内容:Y30非97BC的版本以64级亮度执行
            /*MooncellFpga mooncellFpga = clientsManage.ledCardCommunication.mooncellFpga;
            String oldFpgaVersion = mooncellFpga.getFpgaVersion();//FPGA版本
            String cardName = ledCardCommunication.GetSerialNumber();//卡号
            if (cardName.startsWith("Y30") && !"0x97BC".equals(oldFpgaVersion) && brightness<=64){
                brightness *=4;
            } else if (brightness > 64){
                return false;
            }*/
            //update end
            boolean result= ledCardCommunication.LightPro(manual,brightness);
            int count = 0;
            if (!result){
                while (true){
                    count++;
                    MyLog.i("ledCardCommunication.LightPro..........."+brightness);
                    result = ledCardCommunication.LightPro(manual,brightness);
                    MyLog.sleepForMillisecond(1000);
                    if (result){
                        count = 0;
                        break;
                    }
                    if (count>20){
                        //退出本程序
                        MyLog.i("exit display.....");
                        System.exit(0);
                    }
                }
            }
            return result;
        }

        /*
        获取屏幕亮度
         */
        @Override
        public int getBrightness() throws RemoteException {
            if (ledCardCommunication == null){
                ledCardCommunication = clientsManage.ledCardCommunication;
            }
            int result = ledCardCommunication.getBrightness();
//            MyLog.i("getBrightness==============="+result);
            //update start定制内容:Y30非97BC的版本以64级亮度执行
           /* MooncellFpga mooncellFpga = clientsManage.ledCardCommunication.mooncellFpga;
            String oldFpgaVersion = mooncellFpga.getFpgaVersion();//FPGA版本
            String cardName = ledCardCommunication.GetSerialNumber();//卡号
            if (cardName.startsWith("Y30") && !"0x97BC".equals(oldFpgaVersion)){
                return result/4;
            }*/
            //update end
            return result==256 ? 255 : result;
        }

        /*
        获取接收卡数量
         */
        @Override
        public int getReceivedCardNum() throws RemoteException {
            MooncellFpga mooncellFpga = clientsManage.ledCardCommunication.mooncellFpga;
            int port1 =  mooncellFpga.ReceivedCard_GetNumber(0,0xF);//接收卡数量
            int port2 =  mooncellFpga.ReceivedCard_GetNumber(1,0xF);//接收卡数量
            MyLog.i("port1=="+port1+";port2="+port2);
            return port1+port2;
        }

        /*
        获取3288系列卡fpga版本
         */
        @Override
        public int getVersionBy3288() throws RemoteException {
            if (ledCardCommunication == null){
                ledCardCommunication = clientsManage.ledCardCommunication;
            }
            MooncellFpga mooncellFpga = clientsManage.ledCardCommunication.mooncellFpga;
            int fpgaVersion =  mooncellFpga.getFpgaVersion();
//            MyLog.i("fpgaVersion:"+fpgaVersion);
            return fpgaVersion;
        }

        //设置偏移
        @Override
        public int setOffset(int screenX, int screenY,int cutW,int cutH, int so1X, int so1Y, int so2X, int so2Y) throws RemoteException {
            return clientsManage.ledCardCommunication.mooncellFpga.setOffset(screenX,screenY,cutW,cutH,so1X,so1Y,so2X,so2Y);
        }
    }

    public int readFpgaInfo() {
        MyLog.i("registerFpgaInfoBroadcast.......");
        byte[] fpgacmd = {0x7E,0x7E,0x55,0x7C,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x00, (byte) 0xE6,0x0C,0x00,0x00, (byte) 0x8D};
        byte[] newFpgacmd = new byte[65];
        byte[] fpgatemp = null;
        System.arraycopy(fpgacmd, 0, newFpgacmd, 0, fpgacmd.length);
//                Define.showBytes("fpgacmd",newFpgacmd,0);
        //请求fpga
        int res = clientsManage.ledCardCommunication.mooncellFpga.spiDevice.Operator(newFpgacmd,newFpgacmd.length);
        fpgacmd = new byte[49];
        System.arraycopy(newFpgacmd, 17, fpgacmd, 0, fpgacmd.length-1);
//                Define.showBytes("fpgacmdback",fpgacmd,0);
        if (res > 0 && fpgacmd != null){
//            MyLog.showBytes("fpgacmd",fpgacmd,0);
            /*if (!Arrays.equals(fpgacmd,fpgatemp)){//如果数据相同就不需要发送
                fpgatemp = fpgacmd;
                if (ledCardCommunication != null){
                    MyLog.i("sendToCardSystem..............");
//                    ledCardCommunication.sendToCardSystem(fpgacmd);
                } else{
                    MyLog.i("------------ledCardCommunication = null ");
                }
            }*/
        }else {
            MyLog.i("fpgacmd send fail or back is null...");
        }
        newFpgacmd = new byte[65];
        MyLog.showBytes("newFpgacmd===",newFpgacmd,0);
        return 0;
    }

    @Override
    public void onCreate() {
        super.onCreate();

        Log.i("_yzd", "display service on create");
        CreateWorkFolder();

        InitialWorkParams();

//        registerBrightnessBroadcast();

        registerRebootBroadcast();

        fw_receiver = new BreakpointReceiver();
        IntentFilter fw_filter = new IntentFilter();
        fw_filter.addAction("com.xixun.pixel.detect");
        registerReceiver(fw_receiver, fw_filter);

        RefreshDisplayInitail();

        new Thread() {
            public void run() {
                Process();
            }
        }.start();
    }

    public void SendMessage(int iMessage,String strCommand)
    {
        if (handlerRefreshDisplay==null) return;
        Message msg = handlerRefreshDisplay.obtainMessage(iMessage,strCommand);
        handlerRefreshDisplay.sendMessage(msg);
    }



    private void RefreshDisplayInitail() {
        handlerRefreshDisplay = new Handler() {
            public void handleMessage(Message msg) {
                String string = (String) msg.obj;
                MyLog.i("==============================Msg.ID:" + msg.what + ",Params:" + string);
                switch (msg.what)
                {
                    case MSG_CHANGE_APP_RESTART:
                        MyLog.i( " "+ Thread.currentThread().getStackTrace()[2].getFileName() + "-->"
                                +   "Function: " +Thread.currentThread().getStackTrace()[2].getMethodName() + "-->"
                                +   "Line" +Thread.currentThread().getStackTrace()[2].getLineNumber() + ": Received Restart Command.\r\n"
                        );
                        System.exit(0);
                        break;
                    case MSG_CHANGE_INFOMATIONS_BASE:
                    {  int iCommandParamsStart=string.indexOf('=');
                        if (iCommandParamsStart>0) {
                            int iOffset=0;
                            for (iOffset=0;iOffset<string.length();iOffset++)
                            {   char ucChar=string.charAt(iOffset);
                                if (ucChar>=0x21 && ucChar<0x80) break;
                            }
                            String strCommand=string.substring(iOffset,iCommandParamsStart); // 2: 发送方会以UTF格式自动添加2个字节的标识长度.
                            iCommandParamsStart++;
                            String strParams=string.substring(iCommandParamsStart);

                            //MyLog.i("strCommand: " + strCommand +";  strParams: " + strParams);

                        }
                    }
                    break;
                }
                super.handleMessage(msg);
            }
        };
    }

    @Override
    public void onDestroy() {
        Log.i("_yzd", "destroy display service");
        if( receiver_brightness != null) {
            unregisterReceiver(receiver_brightness);
            receiver_brightness = null;
        }
        if (LedCardCommunication.receiver != null) {
            unregisterReceiver(LedCardCommunication.receiver);
            LedCardCommunication.receiver = null;
        }
        if( isBound_IUartService ) {
            unbindService(serviceConnection_IUartService);
            isBound_IUartService = false;
        }
        if(isBound_PlayerInfo) {
            unbindService(serviceConnection_PlayerInfo);
            isBound_PlayerInfo = false;
        }
        if( fw_receiver != null) {
            unregisterReceiver(fw_receiver);
        }
        MyLog.i(" "+ Thread.currentThread().getStackTrace()[2].getFileName() + "-->"
                +   "Function: " +Thread.currentThread().getStackTrace()[2].getMethodName() + "-->"
                +   "Line" +Thread.currentThread().getStackTrace()[2].getLineNumber() + ":\r\n"
        );
        super.onDestroy();
    }

    public boolean isAppForeground(Context context){
        return true;
    }

    public class  BreakpointReceiver extends BroadcastReceiver{

        @Override
        public void onReceive(Context context, Intent intent) {

            if( intent.getAction().equals("com.xixun.pixel.detect") )
            {
                try {
                    MyLog.i("----------- " + intent.getAction().equals("com.xixun.pixel.detect"));
                    if (clientsManage != null && clientsManage.ledCardCommunication != null && clientsManage.ledCardCommunication.mooncellFpga != null) {
                        String data = clientsManage.ledCardCommunication.mooncellFpga.check_bad_led();
                        Intent intent_fw = new Intent("com.xixun.pixel.detect.answer");
                        intent_fw.putExtra("data", data);
                        sendBroadcast(intent_fw);
                    }
                }catch(Exception e){e.printStackTrace();}
            }

        }
    }

    /*private void registerBrightnessBroadcast() {
        IntentFilter filter = new IntentFilter();
        filter.addAction("xixun.intent.action.REFRESH_BRIGHTNESS");
        receiver_brightness = new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
                brightness = intent.getIntExtra("brightness", 0);
                manual = intent.getBooleanExtra("manual", true);
                if (ledCardCommunication == null){
                    ledCardCommunication = clientsManage.ledCardCommunication;
                }
                boolean result= ledCardCommunication.LightPro(brightness);
                if (!result){//再尝试一遍
                    MyLog.i("ledCardCommunication.LightPro..........."+brightness);
                    result = ledCardCommunication.LightPro(brightness);
                }
                MyLog.sleepForMillisecond(200);
                if (!result){
                    //退出本程序
                    MyLog.i("exit display.....");
                    System.exit(0);
                }
            }
        };
        this.registerReceiver(receiver_brightness, filter);
    }*/

    public boolean Get_Manual(){
        return manual;
    }

    //=========================    2019 2 20===========================================================
    // modified byfw 2019-2-20    --start   收到reboot后屏幕亮度调位0， 针对old-Y30 reboot出现企鹅问题。
    public static String REBOOT = "xixun.intent.action.REBOOT";
    BroadcastReceiver receiver_reboot = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            if (REBOOT.equals(intent.getAction())) {
                LedCardCommunication.reboot_cmd = true;
                MyLog.i("------------rebootcmd");

            }else
                LedCardCommunication.reboot_cmd = false;
        }
    };
    private void registerRebootBroadcast() {
        IntentFilter filter = new IntentFilter();
        filter.addAction(REBOOT);

        this.registerReceiver(receiver_reboot, filter);
    }
    // modified byfw 2019-2-20    --end
    //====================================================================================

    private static void closeStream(Closeable stream) {
        if (stream != null) {
            try {
                stream.close();
            } catch (Exception e) {
                // nothing
            }
        }
    }

    void Process()
    {
        if (bUseSerialPort) {           // false
            Aidl_SerialPortsInitial();
            System.out.printf("124124414");

            while (NeedExit() == false) {
                if (serialPorts != null) break;
                MyLog.i("Wait serialPorts connect.");
                try {
                    sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }

        Aidl_PlayerInfo();

        if (!NeedExit()) {
            Clients_Register();         //客户机的注册
            while (!NeedExit())
            {
                try {
                    Thread.sleep(5000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                if (clientsManage==null) break;
                if (clientsManage.NeedExit()) break;
            }
            Clients_UnRegister(null);
            MyLog.i("Clients_UnRegister ");
        }
        MyLog.i(" "+ Thread.currentThread().getStackTrace()[2].getFileName() + "-->"
                +   "Function: " +Thread.currentThread().getStackTrace()[2].getMethodName() + "-->"
                +   "Line" +Thread.currentThread().getStackTrace()[2].getLineNumber() + ":\r\n"
        );
    }

    public void Clients_Register() // 设备注册。
    {   Clients_UnRegister(null);
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        clientsManage=new ClientsManage(this);
    }

    public void Clients_UnRegister(String displayID) // 设备注销，displayID:null,对所有显示屏操作。
    {   if (clientsManage!=null)
        clientsManage.Exit(displayID);
        if (displayID==null) clientsManage=null;
    }

    ServiceConnection serviceConnection_IUartService = new ServiceConnection() {
        @Override
        public void onServiceDisconnected(ComponentName name) {
            serialPorts = null;
            MyLog.i(" "+ Thread.currentThread().getStackTrace()[2].getFileName() + "-->"
                    + "Function: " + Thread.currentThread().getStackTrace()[2].getMethodName() + "-->"
                    + "Line" + Thread.currentThread().getStackTrace()[2].getLineNumber() + " Serial Exit.\r\n"
            );
            System.exit(0);
        }

        @Override
        public void onServiceConnected(ComponentName name, IBinder iBinder) {
            try {
                serialPorts = IUartService.Stub.asInterface(iBinder);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    };

    public void Aidl_SerialPortsInitial() {
        try {
            Intent intent = new Intent("xixun.intent.action.UART_SERVICE");
            intent.setPackage("com.xixun.joey.cardsystem");
            isBound_IUartService = bindService(intent, serviceConnection_IUartService, BIND_AUTO_CREATE); // add byfw  2019/1/30
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    ServiceConnection serviceConnection_PlayerInfo = new ServiceConnection() {
        @Override
        public void onServiceDisconnected(ComponentName name) {
            playerInfo = null;
            MyLog.i(" "+ Thread.currentThread().getStackTrace()[2].getFileName() + "-->"
                    + "Function: " + Thread.currentThread().getStackTrace()[2].getMethodName() + "-->"
                    + "Line" + Thread.currentThread().getStackTrace()[2].getLineNumber() + " PlayerInfo Exit.\r\n"
            );
        }

        @Override
        public void onServiceConnected(ComponentName name, IBinder iBinder) {
            try {
                playerInfo = PlayerInfo.Stub.asInterface(iBinder);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    };


    public void Aidl_PlayerInfo() {
        try {

            Intent intent = new Intent(ACTION_PLAYER);
            intent.setPackage(PACKAGE_PLAYER);
            //  bindService(intent, serviceConnection_PlayerInfo, BIND_AUTO_CREATE);
            isBound_PlayerInfo =  bindService(intent, serviceConnection_PlayerInfo, BIND_AUTO_CREATE);   // add byfw  2019/1/30
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    void CreateWorkFolder()
    {   File file =null;
        // 优先SD卡存储目录，空间比较大：M50：16GB。
        strStoragePath= Define.SD_CARD_PATH;           //"/mnt/sdcard/"
        Define.CreateFolder(strStoragePath+Define.STORAGE_PATH);  //STORAGE_PATH = “Sysolution”
        file = new File(strStoragePath + Define.STORAGE_PATH);
        if (file.exists()==false) {
            // 固定存储目录，空间比较比较小：Y卡：512MB。
            strStoragePath = Define.ROOT_PATH;   // “/”
            Define.CreateFolder(strStoragePath + Define.STORAGE_PATH);
            file = new File(strStoragePath + Define.STORAGE_PATH);

            // 均无存储空间，就放在APP安装目录下，卸载或升级参数易丢失。
            if (file.exists() == false) {
                strStoragePath = GetAppPath();
                Define.CreateFolder(strStoragePath + Define.STORAGE_PATH);
            }
        }
        MyLog.i("strStoragePath= " +strStoragePath);

        Define.CreateFolder(strStoragePath+Define.WORK_FILES_PATH);
        Define.CreateFolder(strStoragePath+Define.RECE_FILES_PATH);
    }

    public String GetAppPath()
    {
        return getApplicationContext().getFilesDir().getAbsolutePath()+"/..";
    }

    public void InitialWorkParams()
    {
        workParams = new WorkParams(this,this.getApplicationContext());
    }


    public void AppRestart(){
        System.exit(0);
    }

    boolean NeedExit() { return bNeedExit; }

    public static final int MSG_CHANGE_NONE=0;
    public static final int MSG_CHANGE_APP_RESTART=MSG_CHANGE_NONE+1;
    public static final int MSG_CHANGE_INFOMATIONS_BASE= MSG_CHANGE_NONE + 100;
    static final String ACTION_PLAYER ="com.xixun.action.PlayerInfo";
    public static final String PACKAGE_PLAYER="com.xixun.xixunplayer";
}
