package kr.co.icontrols.ilp300_700.admin.test;

import android.content.Context;
import android.content.Intent;
import android.hardware.Camera;
import android.hardware.Camera.Size;
import android.util.Log;
import android.view.KeyEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceHolder.Callback;
import android.view.SurfaceView;
import android.view.View;
import android.widget.RelativeLayout;

import java.io.IOException;
import java.util.List;

import kr.co.icontrols.ilp300_700.MainActivity;
import kr.co.icontrols.ilp300_700.R;
import kr.co.icontrols.ilp300_700.global.Configure.ConfigValue;
import kr.co.icontrols.ilp300_700.global.DataClasses.POSITION;
import kr.co.icontrols.ilp300_700.global.Declare;
import kr.co.icontrols.ilp300_700.global.ID;
import kr.co.icontrols.wallpadsupport.WpadImageView;
import kr.co.icontrols.wallpadsupport.WpadScreen;
import kr.co.icontrols.wallpadsupport.WpadTextView;
import kr.co.icontrols.wallpadsupport.WpadUtil;

public class AdminSet_Test_Camera extends WpadScreen {

    String TAG = "AdminSet_Test_Camera";

    boolean bLOG = true;   // true, false
    boolean bLOG_DEBUG = true;   // true, false
    boolean bLOG_INFO = true;   // true, false

    WpadImageView Image_Background;
    WpadTextView Text_Title;
    WpadTextView Text_Line_01_Item;
    WpadTextView Text_Line_02_Item;

    int nFontSize_Instruction = 28;
    boolean bFontNonBold = false;
    boolean bFontBold = true;

    Context mContext;

    RelativeLayout CamPreLayout;   // 카메라 영상
    SurfaceView CamPreSurfaceView;
    SurfaceHolder CamPreSurfaceHolder;
    Camera mCamera;

    private static final int MIN_BRIGHTNESS = 0;
    private static final int DEFAULT_BRIGHTNESS = 10;
    private static final int MAX_BRIGHTNESS = 20;
    private static final int MIN_CONTRAST = 0;
    private static final int DEFAULT_CONTRAST = 128;
    private static final int MAX_CONTRAST = 255;

    private Callback CamPreCallback = new Callback() {
        @Override
        public void surfaceCreated(SurfaceHolder holder) {
            try {
                LOG_INFO("[CamPreCallback] surfaceCreated!!");
                MainActivity.mIOInterface.setAnalogCameraPower(true);
                mCamera = Camera.open();
                mCamera.setPreviewDisplay(holder);
            } catch (IOException e) {
                Log.e(TAG, "[Exception] CamPreCallback -> surfaceCreated(...) : " + e);
                e.printStackTrace();
            }
        }

        @Override
        public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
            try {
                LOG_INFO("[CamPreCallback] surfaceChanged!!");

                Camera.Parameters parameters = mCamera.getParameters();
                List<Size> sizes = parameters.getSupportedPreviewSizes();
                Size optimalSize = getOptimalPreviewSize(sizes, width, height);
                parameters.setPreviewSize(optimalSize.width, optimalSize.height);
                parameters.setPictureSize(optimalSize.width, optimalSize.height);
                LOG_INFO("[CamPreCallback] surfaceChanged!!  optimalSize.width = " + optimalSize.width + ", optimalSize.height = " + optimalSize.height);
                mCamera.setParameters(parameters);
                mCamera.startPreview();
            } catch (Exception e) {
                Log.e(TAG, "[Exception] CamPreCallback -> surfaceChanged(...) : " + e);
                e.printStackTrace();
            }
        }

        @Override
        public void surfaceDestroyed(SurfaceHolder holder) {
            try {
                LOG_INFO("[CamPreCallback] surfaceDestroyed!!");
                if (mCamera != null) {
                    mCamera.stopPreview();
                    MainActivity.mIOInterface.setAnalogCameraPower(false);
                    mCamera.release();
                    mCamera = null;
                }
            } catch (Exception e) {
                Log.e(TAG, "[Exception] CamPreCallback -> surfaceDestroyed(...) : " + e);
                e.printStackTrace();
            }
        }

        private Size getOptimalPreviewSize(List<Size> sizes, int w, int h) {
            try {
                double ASPECT_TOLERANCE = 0.1;
                double dTargetRatio = (double) w / h;
                if (sizes == null) return null;

                Size OptimalSize = null;
                double dMinDiff = Double.MAX_VALUE;

                int nTargetHeight = h;

                for (Size size : sizes) {
                    double ratio = (double) size.width / size.height;
                    if (Math.abs(ratio - dTargetRatio) > ASPECT_TOLERANCE) continue;
                    if (Math.abs(size.height - nTargetHeight) < dMinDiff) {
                        OptimalSize = size;
                        dMinDiff = Math.abs(size.height - nTargetHeight);
                    }
                }

                if (OptimalSize == null) {
                    dMinDiff = Double.MAX_VALUE;
                    for (Size size : sizes) {
                        if (Math.abs(size.height - nTargetHeight) < dMinDiff) {
                            OptimalSize = size;
                            dMinDiff = Math.abs(size.height - nTargetHeight);
                        }
                    }
                }
                return OptimalSize;
            } catch (Exception e) {
                Log.e(TAG, "[Exception] getOptimalPreviewSize(...) : " + e);
                e.printStackTrace();
                return null;
            }
        }
    };

    public AdminSet_Test_Camera(Context context, RelativeLayout layout) {
        super(context, layout);
        try {
            LOG("------------------ [START - AdminSet_Test_Camera] -------------------");

            mContext = context;
            Initialize();

            Image_Background = new WpadImageView(context, 0, Declare.DeviceInfo.getScreenSizeFullW(ConfigValue.DEVICE_MODELTYPE), Declare.DeviceInfo.getScreenSizeFullH(ConfigValue.DEVICE_MODELTYPE), R.drawable.bg_back, 0, ID.SCREENS.ADMINSET_INQUIRY_LOBBYPHONEINFO.ELEMENTS.IMAGES.BACKGROUND);
            ViewRegistration(layout, Image_Background, 0, 0);

            initMyVideoSurface();
            ((MainActivity) mContext).setAutoScreenChange(ID.SCREENS.Main, MainActivity.nAdminScreenTimeout);

//            mFrontCamOpenCheckHandler.sendEmptyMessage(0); // 테스트코드
        } catch (Exception e) {
            Log.e(TAG, "[Exception] AdminSet_Test_Camera(...) : " + e);
            e.printStackTrace();
        }
    }

    private void LOG(String log) {
        if (bLOG) Log.v(TAG, log);
    }

    private void LOG_DEBUG(String log) {
        if (bLOG_DEBUG) Log.d(TAG, log);
    }

    private void LOG_INFO(String log) {
        if (bLOG_INFO) Log.i(TAG, log);
    }

    protected void Initialize() {
        try {
            LOG("[Initialize] ===== START =====");
        } catch (Exception e) {
            Log.e(TAG, "[Exception] Initialize() : " + e);
            e.printStackTrace();
        }
    }

    @Override
    protected void onClose() {
        try {
            LOG("------------------ [onClose - AdminSet_Test_Camera] -------------------");
            removeMyVideoSurface();

//            // 테스트코드
//            if (mFrontCamOpenCheckHandler != null)
//                mFrontCamOpenCheckHandler.removeMessages(0);
//            videoSet(false);
        } catch (Exception e) {
            Log.e(TAG, "[Exception] onClose() : " + e);
            e.printStackTrace();
        }
        super.onClose();
    }

    @Override
    protected void onBrReceive(Intent intent) {
        try {
            LOG("[onBrReceive] Intent : " + intent);
        } catch (Exception e) {
            Log.e(TAG, "[Exception] onBrReceive(...) : " + e);
            e.printStackTrace();
        }
        super.onBrReceive(intent);
    }

    @Override
    protected void onKeyDown(int keyCode, KeyEvent event) {
        try {
            LOG("[onKeyDown] keyCode [" + keyCode + "], event [" + event + "]");
            if (keyCode == Declare.Button.CANCEL || keyCode == Declare.Button.TACT_CANCEL) {
//                removeMyVideoSurface();
                MainActivity.mIOInterface.ctrlCameraBrightness(DEFAULT_BRIGHTNESS);
                MainActivity.mIOInterface.ctrlCameraContrast(DEFAULT_CONTRAST);
                super.setChangeScreen(ID.SCREENS.AdminSet_Test);
            }

            // 테스트 코드!!!
            else if (keyCode == Declare.Button.NUMBER_01) {
                MainActivity.mIOInterface.ctrlCameraBrightness(MIN_BRIGHTNESS);
            } else if (keyCode == Declare.Button.NUMBER_02) {
                MainActivity.mIOInterface.ctrlCameraBrightness(DEFAULT_BRIGHTNESS);
            } else if (keyCode == Declare.Button.NUMBER_03) {
                MainActivity.mIOInterface.ctrlCameraBrightness(MAX_BRIGHTNESS);
            } else if (keyCode == Declare.Button.NUMBER_04) {
                MainActivity.mIOInterface.ctrlCameraContrast(MIN_CONTRAST);
            } else if (keyCode == Declare.Button.NUMBER_05) {
                MainActivity.mIOInterface.ctrlCameraContrast(DEFAULT_CONTRAST);
            } else if (keyCode == Declare.Button.NUMBER_06) {
                MainActivity.mIOInterface.ctrlCameraContrast(MAX_CONTRAST);
            }
        } catch (Exception e) {
            Log.e(TAG, "[Exception] onKeyDown(...) : " + e);
            e.printStackTrace();
        }
        super.onKeyDown(keyCode, event);
    }

    protected void UpdateScreen() {
        try {
            LOG("[updateScreen] ===== START =====");
        } catch (Exception e) {
            Log.e(TAG, "[Exception] updateScreen() : " + e);
            e.printStackTrace();
        }
    }

    public POSITION getPosition(int nID) {
//        LOG("[updateScreen] ===== START =====");
        POSITION position = new POSITION();
        position.SetPosition(0, 0, 480, 272);
        try {
            switch (nID) {
                case ID.SCREENS.ADMINSET_INQUIRY_LOBBYPHONEINFO.ELEMENTS.IMAGES.BACKGROUND:
                    position.SetPosition(0, 0, 480, 272);
                    return position;

                case ID.SCREENS.ADMINSET_INQUIRY_LOBBYPHONEINFO.ELEMENTS.TEXTS.TITLE:
                    position.SetPosition(0, 24, 480, 40);
                    return position;

                case ID.SCREENS.ADMINSET_INQUIRY_LOBBYPHONEINFO.ELEMENTS.TEXTS.LINE_01_Item:
                    position.SetPosition(30, 73, 450, 40);
                    return position;

                case ID.SCREENS.ADMINSET_INQUIRY_LOBBYPHONEINFO.ELEMENTS.TEXTS.LINE_02_Item:
                    position.SetPosition(30, 122, 450, 40);
                    return position;

                case ID.SCREENS.ADMINSET_INQUIRY_LOBBYPHONEINFO.ELEMENTS.TEXTS.LINE_03_Item:
                    position.SetPosition(30, 171, 450, 40);
                    return position;

                case ID.SCREENS.ADMINSET_INQUIRY_LOBBYPHONEINFO.ELEMENTS.TEXTS.LINE_04_Item:
                    position.SetPosition(30, 220, 450, 40);
                    return position;

                default:
                    return position;
            }
        } catch (Exception e) {
            Log.e(TAG, "[Exception] getPosition() : " + e);
            e.printStackTrace();
            return position;
        }
    }

    private boolean initMyVideoSurface() {
        try {
            LOG("[initMyVideoSurface] ====== START ======");
            CamPreLayout = new RelativeLayout(mContext);
            WpadUtil.LayoutRegistration(MainActivity.EntireLayout, CamPreLayout, 480, 272, 0, 0, ID.ACTIVITIES.MAINACTIVITY.LAYOUTS.TestCamera);

            RelativeLayout.LayoutParams Params = new RelativeLayout.LayoutParams(480, 272);
            Params.setMargins(0, 0, 0, 0);

            CamPreSurfaceView = new SurfaceView(mContext);
            CamPreSurfaceHolder = CamPreSurfaceView.getHolder();
            CamPreLayout.addView(CamPreSurfaceView, Params);
            CamPreSurfaceView.getHolder().addCallback(CamPreCallback);
            return true;
        } catch (Exception e) {
            Log.e(TAG, "[Exception] initMyVideoSurface() : " + e);
            e.printStackTrace();
            return false;
        }
    }

    private boolean removeMyVideoSurface() {
        try {
            LOG("[removeMyVideoSurface] ===== START =====");
            if (CamPreSurfaceView != null) {
                CamPreSurfaceView.setVisibility(View.GONE);
                CamPreSurfaceView.getHolder().removeCallback(CamPreCallback);
                CamPreSurfaceView = null;
            }
            if (CamPreLayout != null) {
                CamPreLayout.setVisibility(View.GONE);
                CamPreLayout.removeAllViews();
                CamPreLayout = null;
            }
            return true;
        } catch (Exception e) {
            Log.e(TAG, "[Exception] removeMyVideoSurface() : " + e);
            e.printStackTrace();
            return false;
        }
    }

//    // 테스트코드
//    private void videoSet(final boolean bSet) {
//        Log.d(TAG, "[videoSet] bSet [" + bSet + "]");
//        try {
//            Runnable runnable = new Runnable() {
//                @Override
//                public void run() {
//                    if (!bSet) {
//                        MainActivity.mCallController.mVideoJNI.setCheckIFrame(false);
//                        MainActivity.mCallController.mVideoJNI.encoderStopOperation();
//                        MainActivity.mCallController.mVideoJNI.decoderStopOperation();
//                    } else if (bSet) {
//                        MainActivity.mCallController.mVideoJNI.setCheckIFrame(true);
//                        MainActivity.mCallController.mVideoJNI.setCameraSurface(null, 640, 480, 0, 0);
//                        MainActivity.mCallController.mVideoJNI.encoderStartOperation();
//                        MainActivity.mCallController.mVideoJNI.decoderStartOperation();
//                    }
//                }
//            };
//            if (runnable != null) ((MainActivity) mContext).runOnUiThread(runnable);
//        } catch (Exception e) {
//            Log.e(TAG, "[Exception] startVideoEncoding(final boolean bSet, final boolean bEncoding, final boolean bDecoding)");
//            e.printStackTrace();
//            return;
//        }
//    }
//
//    // 테스트 코드
//    public Handler mFrontCamOpenCheckHandler = new Handler() {
//        @Override
//        public void handleMessage(Message msg) {
//            LOG("[mFrontCamOpenCheckHandler] msg.what = " + msg.what);
//            if (msg.what == 0) {
//                if (mCamera != null)
//                    mFrontCamOpenCheckHandler.sendEmptyMessageDelayed(1, 10);
//                else mFrontCamOpenCheckHandler.sendEmptyMessageDelayed(0, 10);
//            } else if (msg.what == 1) {
//                Log.d(TAG, "[mFrontCamOpenCheckHandler] [CAMERA OPEN!!!] seulki");
//                videoSet(true);
//            }
//        }
//    };
}