package com.example.camera1

import android.Manifest
import android.content.pm.PackageManager
import android.graphics.Color
import android.os.AsyncTask
import android.os.Build
import android.os.Bundle
import android.util.Log
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import androidx.camera.core.*
import androidx.camera.lifecycle.ProcessCameraProvider
import androidx.camera.video.Recorder
import androidx.camera.video.Recording
import androidx.camera.video.VideoCapture
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat
import com.example.camera1.databinding.ActivityMainBinding
import java.io.File
import java.nio.ByteBuffer
import java.util.concurrent.ExecutorService
import java.util.concurrent.Executors
import android.view.ViewGroup

import android.R





private var nj  = 0
private var kmin = 0
private var nseed = -1 // nseed < 32768
private var faceCix = 0
private var cicc  = 0 // 1:camera_Input; 2:color_calibration
private var ffok  = 0 // 1~6:input_data is ok for ffok-face
private var ccok  = 0 // 1:color_calibration is ok
private var ddok  = 0 // 1:calibration_data is ok
private var id33  = 0
private var disC  = 0 // edit : px2dp*ratio[0:3],offbt*ratio[4:7],nRow,nCol,gHdp,gWdp,disC
private var ratio = doubleArrayOf(1.0,1.0,1.0,1.0,0.5,0.5,0.5,0.5,2.0,4.0,50.0,50.0,0.0)
private var nRow  = 0 // max 15
private var nCol  = 5 // max 15
private var bHdp  = 120  // 100 120 150
private var gWdp  = 50 // Edit file ratioRCH.txt to change ratio[0:7],gWdp,disC
private var gHdp  = 50 // max 110 // Use (-)(+)Button to change nRow,nCol,gHdp
private var Hval = IntArray(226)
private var R    = IntArray(226)
private var G    = IntArray(226)
private var B    = IntArray(226)
private var cameraON = -1 // 1:-1 --> ON:OFF
private var rtD   = 90  // (0,90,180,270) CW
private var dpW   = 360 // 360 592  423 705
private var dpH   = 568 // 568 336  681 399
private var imW   = intArrayOf(640,320,320,1920)  // 120*16 moto x4  2.56x4.56 in
private var imH   = intArrayOf(480,240,240,1080)  // 120*9  moto x4  65  x 116 mm
private var stP   = intArrayOf(  1,  2,  2)
private var stR   = intArrayOf(640,640,640)
private var px2dp = doubleArrayOf(1.13,0.56,0.56) // 640/568 320/568 320/568
private var pix33 = IntArray(678) // pix33[15*15+1][3] // [226*3]
private var pixss = IntArray(678) // pixss[15*15+1][3] // [226*3]
private var dsize = intArrayOf(307200,153599,153599,90,0,113,360,568,640,480,-240,189,451,68)
private var image0 = ByteArray(307200) // debug
private var image1 = ByteArray(153599)
private var image2 = ByteArray(153599)
private var imgsiz = intArrayOf(307200,153599,153599,307200,153599,153599,307200,153599,153599)
private var answer = " "
private var answerL = " "
private var info = -1
private var idf  = 0

typealias LumaListener = (luma: Double) -> Unit


class MainActivity : AppCompatActivity() {
    private lateinit var viewBinding: ActivityMainBinding

    private var imageCapture: ImageCapture? = null

    private var videoCapture: VideoCapture<Recorder>? = null
    private var recording: Recording? = null
    private var argbC = arrayOf(
        Color.argb(255, 255, 192, 203),
        Color.RED,
        Color.GREEN,
        Color.YELLOW,
        Color.argb(255, 255, 165, 0),
        Color.BLUE,
        Color.WHITE,
        Color.argb(0, 0, 0, 0)
    )

    //      val argbC = arrayOf(0xFFFFC0CB,0x7FFF0000,0x7F00FF00,0x7FFFFF00,0xFFFFA500,0x7F0000FF,0x7FFFFFFF,0x00000000)
    private var textC = arrayOf("P", "R", "G", "Y", "O", "B", "W", "S")

    private lateinit var cameraExecutor: ExecutorService

    private class LuminosityAnalyzer(private val listener: LumaListener) : ImageAnalysis.Analyzer {

        private fun ByteBuffer.toByteArray(): ByteArray {
            rewind()    // Rewind the buffer to zero
            val data = ByteArray(remaining())
            get(data)   // Copy the buffer into a byte array
            return data // Return the byte array
        }

        override fun analyze(image: ImageProxy) {

            // pix33 = IntArray(678) // pix33[226*3]          // 1.13 *  60 = 68; 1.08 *  60 =  65
            // pixss = IntArray(678) // pixss[226*3]          // 1.13 *  568=640       =   189+451
            // dsize = intArrayOf(307200,153599,153599, 90, 0,113,360,568,640,480,-240, 189,189,68)
            // dsize = intArrayOf(307200,153599,153599,  0,58,108,592,336,640,480, 320,  58, 58,65)
            // dsize = intArrayOf(307200,153599,153599,180,58,108,592,336,640,480,-320,-422, 58,65)
            // dsize = intArrayOf(307200,153599,153599, 90, 0, 94,423,681,640,480,-240, 264,264,56)
            // dsize = intArrayOf(307200,153599,153599,  0,58, 91,705,399,640,480, 320,  58, 58,54)
            // dsize = intArrayOf(307200,153599,153599,180,58, 91,705,399,640,480,-320,-422, 58,54)
            // px2dp = DoubleArray(3)
            // nRow  = 2
            // nCol  = 4
            // gHdp  = 50
            // imW   = IntArray(3)
            // imH   = IntArray(3)
            // stP   = IntArray(3)
            // stR   = IntArray(3)
            // dpW dpH // 592x336 360x568  705x399 423x681
            var offbt = intArrayOf(0, 0, 0)
            rtD = image.imageInfo.rotationDegrees // 90  (0,90,180,270)
            stP[0] = image.planes[0].pixelStride // 1    ( 1,  2,  2 )
            stR[0] = image.planes[0].rowStride   // 640  (640,640,640)
            imW[0] = image.width                 // 640
            imH[0] = image.height                // 480
            stP[1] = image.planes[1].pixelStride // 2
            stR[1] = image.planes[1].rowStride   // 640
            stP[2] = stP[1]; stR[2] = stR[1]
            var stp0 = (stR[0] / stP[0]) / (stR[1] / stP[1])// 2
            imW[1] = imW[0] / stp0; imW[2] = imW[1]     // 320
            imH[1] = imH[0] / stp0; imH[2] = imH[1]     // 240
            var px2dp0 = 0.0
            var py2dp0 = 0.0; offbt[0] = 0
            if (rtD == 0 || rtD == 180) {                   //  normal   small
                px2dp0 = imW[0].toDouble() / dpW.toDouble() // 640/592  640/705 // 108   91
                py2dp0 = imH[0].toDouble() / dpH.toDouble() // 480/336  480/399 // 143  120
                if (px2dp0 < py2dp0) offbt[0] = (imH[0].toDouble() - px2dp0 * dpH.toDouble()).toInt()
            } else {
                px2dp0 = imH[0].toDouble() / dpW.toDouble() // 480/360  480/423 // 133  113
                py2dp0 = imW[0].toDouble() / dpH.toDouble() // 640/568  640/681 // 113   94
                if (px2dp0 < py2dp0) offbt[0] = (imW[0].toDouble() - px2dp0 * dpH.toDouble()).toInt()
            }
            px2dp[0] = Math.min(px2dp0, py2dp0)
            px2dp[0] = px2dp[0] * ratio[rtD / 90] // ratio[] in dpratio.txt may be edited by user
            px2dp[1] = px2dp[0] * (imH[1].toDouble() / imH[0].toDouble()); px2dp[2] = px2dp[1]
            offbt[1] = offbt[0] * imH[1] / imH[0]; offbt[2] = offbt[1]

            dsize[3] = rtD                                                 //   0  90    0  90
            dsize[4] = (offbt[0].toDouble() * ratio[rtD / 90 + 4]).toInt() //  58   0   58   0
            dsize[5] = (100.0 * px2dp[0] + 0.5).toInt()                    // 108 113   91  94
            dsize[6] = dpW; dsize[7] = dpH; dsize[8] = imW[0]; dsize[9] = imH[0]
            // dsize[10] = px0; dsize[11] = py0; dsize[12] = gWpx; dsize[13] = gHpx
            /*
            println("Format ${image.getFormat()}") // 35
            var mat=FloatArray(9)
            image.imageInfo.sensorToBufferTransformMatrix.getValues(mat)
            for(k in 0..mat.size-1) print("${mat[k]}\n") // 1 0 0  0 1 0  0 0 1 // no use
            var sx=1f; var sy=1f; var px=0f; var py=0f;
            image.imageInfo.sensorToBufferTransformMatrix.postScale(sx,sy,px,py); println("$sx $sy $px $py") // no change
            image.imageInfo.sensorToBufferTransformMatrix.postScale(sx,sy,px,py); println("$sx $sy $px $py") // no use
            println("${image.imageInfo.rotationDegrees} ${image.width} ${image.height}")     // 90 640 480
            println("${image.planes[0].getPixelStride()} ${image.planes[0].getRowStride()}") //  1 640 : 1 640
            println("${image.planes[1].getPixelStride()} ${image.planes[1].getRowStride()}") //  1 320 : 2 640
            println("${image.planes[2].getPixelStride()} ${image.planes[2].getRowStride()}") //  1 320 : 2 640
            */
            answerL = "" // "Analyze"
            answer = ""
            for (k in 0..677) pixss[k] = 0
            for (kk in 0..2) {
                var buffer = image.planes[kk].buffer
                var data = buffer.toByteArray()
                dsize[kk] = data.size     // 307200 153599
                // var pixels = data.map { it.toInt() and 0xFF }
                if (disC >= 4) {
                    var ndata = Math.min(data.size, imgsiz[kk])
                    imgsiz[kk + 3] = ndata
                    imgsiz[kk + 6] = data.size
                    if (kk == 0) for (k in 0 until ndata) image0[k] = data[k] // image0.txt
                    if (kk == 1) for (k in 0 until ndata) image1[k] = data[k] // image1.txt
                    if (kk == 2) for (k in 0 until ndata) image2[k] = data[k] // image2.txt
                    image0[2 * kk] = (4096 * stP[kk] + stR[kk]).shr(7).toByte()
                    image0[2 * kk + 1] = stR[kk].and(0x7F).toByte()
                    image0[6] = imW[0].shr(7).toByte(); image0[7] = imW[0].and(0x7F).toByte()
                    image0[8] = imH[0].shr(7).toByte(); image0[9] = imH[0].and(0x7F).toByte()
                    image0[3 * kk + 10] = ndata.shr(14).toByte()
                    image0[3 * kk + 11] = ndata.shr(7).and(0x7F).toByte()
                    image0[3 * kk + 12] = ndata.and(0x7F).toByte()
                    image0[19] = dsize[5].shr(7).and(0x7F).toByte()
                    image0[20] = dsize[5].and(0x7F).toByte()
                }
                var ij: Int
                var px00: Int
                var pxj0: Int
                var pxij: Int
                var pxdx: Int
                var pxdy: Int
                var stx = 1
                var sty = 1
                var px0 = 0
                var py0 = 0
                var gWpx = (gWdp * px2dp[kk] + 0.5).toInt() // gWdp * 1.13
                var gHpx = (gHdp * px2dp[kk] + 0.5).toInt() // gHdp * 1.13
                var bHpx = (bHdp * px2dp[kk] + 0.5).toInt()
                bHpx = bHpx + ((offbt[kk].toDouble())*ratio[rtD/90+4]).toInt()
                // grid hor/ver spacing = (gWdp)dp
                // guide Width  spacing = (gWdp)dp = (gWpx)px
                // guide Height spacing = (gHdp)dp    // pixel No. at grid bottom center = offset +
                // grid bottom line is at (bHpx)px above screen bottom // (py0)dp * (sty)pixel/dp +
                // grid center line is at the screen center            // (px0)dp * (stx)pixel/dp
                if (rtD == 0) {
                    stx = stP[kk]; sty = stR[kk]; px0 = imW[kk] / 2; py0 = imH[kk] - bHpx
                }
                if (rtD == 90) {
                    stx = -stR[kk]; sty = stP[kk]; px0 = -imH[kk] / 2; py0 = imW[kk] - bHpx
                }
                if (rtD == 180) {
                    stx = -stP[kk]; sty = -stR[kk]; px0 = -imW[kk] / 2; py0 = -bHpx
                }
                if (rtD == 270) {
                    stx = stR[kk]; sty = -stP[kk]; px0 = imH[kk] / 2; py0 = -bHpx
                }
                if (kk == 0) {
                    dsize[10] = px0; dsize[11] = py0; dsize[12] = gWpx; dsize[13] = gHpx
                }

                pxdx = gWpx * stx
                pxdy = gHpx * sty
                px00 = (py0 + gHpx/2 - gHpx*nRow)*sty + (px0 - (nCol-1)*gWpx/2)*stx
                answer = answer + "\n${(px2dp[kk]*100.0).toInt()} : $stx $sty $pxdx $pxdy : $px0 $py0 ${offbt[kk]} $px00"
                for (jj in 0..nRow) {
                    for (ii in 0..nCol - 1) {
                        var ii0 = ii; if (jj == nRow) ii0 = nCol / 2
                        // (YY UV VU)(YY UU VV):no-adjust
                        // if(kk > 0) ii0 = ii0 + (kk-1) // (YY UV UV):adjust by (kk-1)
                        pxj0 = px00 + jj*pxdy + ii0*pxdx
                        ij = 3 * (nCol * jj + ii) + kk
                        for (j in -4..3) {
                            for (i in -4..3) {
                                pxij = pxj0 + (j/stP[kk])*sty + (i/stP[kk])*stx
                                if (pxij < 0 || pxij >= dsize[kk]) continue
                                pixss[ij] += data[pxij].toInt().and(0xFF)
                            }
                        }
                        pix33[ij] = pixss[ij] / 64
                        if (jj == nRow) break
                    }
                }
            }

            var T0 = 0.0
            var T = 0.0
            var Y = 0.0
            var U = 0.0
            var V = 0.0
            var YR = 0.0; var YB = 0.0
            var VR = 0.0; var UB = 0.0
            //  Hval = IntArray(226);  // R[226]; G[226]; B[226]
            var k:  Int
            var k0: Int
            var k1: Int
            var k2: Int
            var k3: Int
            var k4: Int
            var ipmin: Int
            var kpmin: Int
            var kpnxt: Int
            var idif:  Int
            var kk = intArrayOf(1, 2, 0)
            var RGB = DoubleArray(3)
            for(k in 0..225) {R[k]=255; G[k]=255; B[k]=255; Hval[k]=0;}

            for(k in 0..nRow*nCol) {
                Y = pix33[k * 3 + 0].toDouble()
                U = pix33[k * 3 + 1].toDouble()
                V = pix33[k * 3 + 2].toDouble()
                if(Y < 0.0) Y = 0.0; if(Y > 255.0) Y = 255.0
                if(U < 0.0) U = 0.0; if(U > 255.0) U = 255.0
                if(V < 0.0) V = 0.0; if(V > 255.0) V = 255.0

                // Formula 1  for (Y,U,V) to (R,G,B)
                // https://en.wikipedia.org/wiki/YUV
                // Y = 0.299R + 0.587G + 0.114B     // 0.587 = 1 - 0.299 - 0.114
                // U = 0.492(B-Y) // 2.032=1/0.492  // 0.492 = 0.436/(1-0.114)
                // V = 0.877(R-Y) // 1.140=1/0.877  // 0.877 = 0.615/(1-0.299)
                // RGB[0] = Y + 1.140*V             // 0.581 = 1.140*0.299/0.587
                // RGB[1] = Y - 0.395*U - 0.581*V
                // RGB[2] = Y + 2.032*U             // 0.395 = 2.032*0.114/0.587
                // Y = 0.299R+0.587G+0.114B         //              (0:255)
                // U =-0.147R-0.289G+0.436B // (0.147,0.289) = 0.492*(0.299,0.587)
                // V = 0.615R-0.515G-0.100B // (0.515,0.100) = 0.877*(0.587,0.114)
                // Compute Hue of HSV/HSL from RGB // Hue independent to Y
                // U = (U-127.5)*222/255    // (-0.436:0.436)*255 = (-111:111)
                // V = (V-127.5)*312/255    // (-0.615:0.615)*255 = (-156:156)
                // V = (V-127.5)*222/255    // To keep the original ratio
                // RGB[0] = 1.140 * V       // (-178:178)  // Let Y = 0
                // RGB[2] = 2.032 * U       // (-226:226)
                // RGB[1] =-(RGB[0]+RGB[2]) // RGB[0] + RGB[1] + RGB[2] = 0 = Y

                // Formula 2  for (Y,U,V) to (R,G,B)
                // https://nl.wikipedia.org/wiki/YUV
                // Uc = U - 128.0
                // Vc = V - 128.0
                // RGB[0]=Y-0.00093*Uc+1.40169*Vc //Y= 0.299*R+0.587*G+0.114*B
                // RGB[1]=Y-0.34370*Uc-0.71417*Vc //U=-0.169*R-0.331*G+0.500*B+128
                // RGB[2]=Y+1.77216*Uc+0.00099*Vc //V= 0.500*R-0.419*G-0.081*B+128
                // for(k4 in 0..2) {if(RGB[k4] < 0.0) RGB[k4] = 0.0;
                //                  if(RGB[k4]>255.0) RGB[k4] = 255.0;}
                // or
                // Y = 0.299R + 0.587G + 0.114B     // 0.587 = 1 - 0.299 - 0.114
                // U = 0.564(B-Y) // 1.773=1/0.564  // 0.564 = 0.500/(1-0.114)
                // V = 0.713(R-Y) // 1.403=1/0.713  // 0.713 = 0.500/(1-0.299)
                // RGB[0] = Y + 1.403*V             // 0.715 = 1.403*0.299/0.587
                // RGB[1] = Y - 0.344*U - 0.715*V
                // RGB[2] = Y + 1.773*U             // 0.344 = 1.773*0.114/0.587
                // Y = 0.299R+0.587G+0.114B         //          (0:255)
                // U =-0.169R-0.331G+0.500B // (0.169,0.331) = 0.564*(0.299,0.587)
                // V = 0.500R-0.419G-0.081B // (0.419,0.081) = 0.713*(0.587,0.114)
                // Compute Hue of HSV/HSL from RGB // Hue independent to Y
                // U = U - 127.5            // (-0.5:0.5)*255 = (-127:127)
                // V = V - 127.5            // (-0.5:0.5)*255 = (-127:127)
                // RGB[0] = 1.403 * V       // (-178:178)  // Let Y = 0
                // RGB[2] = 1.773 * U       // (-225:225)
                // RGB[1] =-(RGB[0]+RGB[2]) // RGB[0] + RGB[1] + RGB[2] = 0 = Y

                // Formulas 1:4  (R,G,B) -> (Y,U,V) given (YR,YB,UB,VR)
                // UBY = UB / (1.0-YB)    // UB  = 0.436  0.5  0.436  0.5
                // VRY = VR / (1.0-YR)    // VR  = 0.615  0.5  0.615  0.5
                // YG = 1.0 - YR - YB     // YR  = 0.299 0.299 .2126 0.25
                // Y = YR*R + YG*G + YB*B // YB  = 0.114 0.114 .0722 0.25
                // U = UBY*(B-Y)          // UBY = 0.492 0.564 0.470  2/3
                // V = VRY*(R-Y)          // VRY = 0.877 0.713 0.781  2/3
                // U = UR*R + UG*G + UB*B // TV     SDTV        HDTV
                // V = VR*R + VG*G + VB*B // BT     470   601   709
                // Formulas 1:3  (Y,U,V) -> (R,G,B) given (YR,YB,UB,VR)
                // UBY = UB / (1.0-YB)    // UBY = 0.492 0.564 0.470  2/3
                // VRY = VR / (1.0-YR)    // VRY = 0.877 0.713 0.781  2/3
                // B = Y + U / UBY        //1/UBY= 2.032 1.773 2.128  1.5
                // R = Y + V / VRY        //1/VRY= 1.140 1.403 1.280  1.5
                // G = Y - V / VRY - U / UBY

                // Computation: Choose one of four methods
                // YR = 0.299; YB = 0.114; VR = 0.615; UB = 0.436 // method 1
                // YR = 0.299; YB = 0.114; VR = 0.5;   UB = 0.5   // method 2
                // YR =0.2126; YB =0.0722; VR = 0.615; UB = 0.436 // method 3
                YR = 0.25;  YB = 0.25;  VR = 0.5;   UB = 0.5   // method 4
                // YR,YB,VR,UB given      // YG =  1.0 - YR - YB
                var UBY = UB / (1.0-YB)   // UR = -UBY * YR; UG = -UBY * YG
                var VRY = VR / (1.0-YR)   // VB = -VRY * YB; VG = -VRY * YG
                var UVS = VR;  if(UB < VR) UVS = UB   // UVS = min(UB,VR)
                var US = (U - 127.5) * UVS * 2  // US : (-127:127) * UVS * 2
                var VS = (V - 127.5) * UVS * 2  // VS : (-127:127) * UVS * 2
                RGB[0] =  VS / VRY        // Let Y = 0 (Hue not depend on Y)
                RGB[2] =  US / UBY
                RGB[1] = -(RGB[0]+RGB[2]) // RGB[0] + RGB[1] + RGB[2] = 0 = Y

                // Compute Hue from RGB[0:2]
                k0 = 0; for (k4 in 0..2) {if(RGB[k4] > RGB[k0]) k0 = k4;}
                k1 = kk[k0]; k2 = kk[k1]                    // max: RGB[k0]
                if(RGB[k1] < RGB[k2]) k3 = k1; else k3 = k2 // min: RGB[k3]
                var D = RGB[k0] - RGB[k3]; var H = 0.0    //     R  G   B
                if(D>0) H=40*(RGB[k1]-RGB[k2])/D+80*k0+40 // H=(0:80:160:240)
                if(D>255) {RGB[0] = RGB[0]*255/D;
                    RGB[1] = RGB[1]*255/D;
                    RGB[2] = RGB[2]*255/D;}
                // Compute Y and add to RGB[0:2] for color of Buttons
                Y = 127.5-(RGB[k0]+RGB[k3])/2.0 // Y from video is not used
                // To put RGB[0:2] in the middle of (0:255)
                RGB[0] = RGB[0] + Y; R[k] = RGB[0].toInt()
                RGB[1] = RGB[1] + Y; G[k] = RGB[1].toInt()
                RGB[2] = RGB[2] + Y; B[k] = RGB[2].toInt()
                Hval[k] = H.toInt()  // Hue of HSV/HSL
                answerL += "${pix33[k*3]} ${pix33[k*3+1]} ${pix33[k*3+2]} : "
                answerL += "${R[k]} ${G[k]} ${B[k]} : ${Hval[k]} : ${k+1}"
                if(dpW<dpH || k%2==1) answerL += "\n"; else answerL += "  "
            }

            ipmin = 32767
            kpmin = nRow * nCol
            for (kp in 0..nRow * nCol - 1) {
                var idif = 0
                for (k in 0..2) idif += Math.abs(pix33[3 * nRow * nCol + k] - pix33[3 * kp + k])
                if (idif <= ipmin) {
                    ipmin = idif
                    kpmin = kp
                }
            }
            ipmin = 32767
            kpnxt = nRow * nCol
            for (kp in 0..nRow * nCol - 1) {
                if (kp == kpmin) break
                var idif = 0
                for (k in 0..2) idif += Math.abs(pix33[3 * nRow * nCol + k] - pix33[3 * kp + k])
                if (idif <= ipmin) {
                    ipmin = idif
                    kpnxt = kp
                }
            }
            answerL = answerL + "ID = ${kpmin+1} ${kpnxt+1} "

            ipmin = 32767
            kpmin = nRow * nCol
            for (kp in 0..nRow * nCol - 1) {
                idif = Math.abs(Hval[nRow * nCol] - Hval[kp])
                if(idif > 120) idif = 240 - idif
                if (idif <= ipmin) {
                    ipmin = idif
                    kpmin = kp
                }
            }
            answerL = answerL + "${kpmin+1}" + " ${dpW} ${dpH} ${disC}" + answer

            val luma = kpmin.toDouble()

            listener(luma)

            image.close()
        }
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        viewBinding = ActivityMainBinding.inflate(layoutInflater)
        setContentView(viewBinding.root)

        // Request camera permissions
        if (allPermissionsGranted()) {
            startCamera()
        } else {
            ActivityCompat.requestPermissions(
                this, REQUIRED_PERMISSIONS, REQUEST_CODE_PERMISSIONS
            )
        }

        // Set up the listeners for take photo and video capture buttons
        // viewBinding.imageCaptureButton.setOnClickListener { takePhoto() }
        // viewBinding.videoCaptureButton.setOnClickListener { captureVideo() }
        viewBinding.face00Button.setOnClickListener { saveRowCol() }   // save ratio[8],nRow,nCol,gHdp
        viewBinding.face01Button.setOnClickListener { changeRow(-1) }  // nRow-1
        viewBinding.face02Button.setOnClickListener { changeRow(0) }   // nRow
        viewBinding.face03Button.setOnClickListener { changeRow(1) }   // nRow+1
        viewBinding.face04Button.setOnClickListener { changeCol(-1) }  // nCol-1
        viewBinding.face05Button.setOnClickListener { changeCol(0) }   // nCol
        viewBinding.face06Button.setOnClickListener { changeCol(1) }   // nCol+1
        viewBinding.face07Button.setOnClickListener { changegHdp(-1) } // gHdp-1
        viewBinding.face08Button.setOnClickListener { changegHdp(0) }  // gHdp
        viewBinding.face09Button.setOnClickListener { changegHdp(1) }  // gHdp+1
        viewBinding.face10Button.setOnClickListener { setCameraON(0) } // cameraON = 1:-1 --> ON:OFF
        viewBinding.solutionL.setOnClickListener { dispInfo(-1) }
        cameraExecutor = Executors.newSingleThreadExecutor()

        if (savedInstanceState != null) { // For a previously destroyed instance.
            var nseed = -1
        } else { // For a new instance.
            var nseed = -1
            // AsyncTask.execute { setTable(2) }
        }
        faceCix = 1; ddok = 0; ffok = 0; answer = " "
        dispInfo(0) // also set info = 0
        val externalStorageVolumes: Array<out File> =
            ContextCompat.getExternalFilesDirs(applicationContext, null)
        val fileratio = File(externalStorageVolumes[0], "ratioRCH.txt")
        if (!fileratio.exists()) {
            // ratio = doubleArrayOf(1.0,1.0,1.0,1.0,0.5,0.5,0.5,0.5,.....)
            nRow = 2; nCol = 5; gHdp = 50; gWdp = 50; disC = 0
            saveRowCol()
        } else {
            var ratbb = fileratio.readBytes()
            var ratp = 0
            var ratd = 1
            var ratx = 1
            var kk   = 0
            for (k in 0 until ratbb.size) {
                var ratk = ratbb[k].toInt() - 48
                if (ratk == -2) {
                    ratx = 10; continue
                }
                if (ratk < 0 || ratk > 9) {
                    if (ratp == 0 && ratx == 1) continue // OK: 1  1.25  0.800  0.0  0.  .0
                    ratio[kk] = ratp.toDouble() / ratd.toDouble() // NG: 0  00
                    ratp = 0; ratd = 1; ratx = 1
                    if (kk >= 12) break
                    kk = kk + 1
                } else {
                    ratp = ratp * 10 + ratk
                    ratd = ratd * ratx
                }
            }
            if (ratp > 0 || ratx > 1) ratio[kk] = ratp.toDouble() / ratd.toDouble()
            if (nRow == 0) {
                nRow = ratio[8].toInt()
                nCol = ratio[9].toInt()
                gHdp = ratio[10].toInt()
                gWdp = ratio[11].toInt()
                disC = ratio[12].toInt()
            }
        }
        setCameraON(1) // also dispGrid(6) and set cameraON = 1
        dpW = getResources().getConfiguration().screenWidthDp  // 360 592  423 705
        dpH = getResources().getConfiguration().screenHeightDp // 568 336  681 399
        dispButton()
        dispInfo(0)
        dispVal(nRow*nCol+1)
    }

    private fun startCamera() {
        val cameraProviderFuture = ProcessCameraProvider.getInstance(this)

        cameraProviderFuture.addListener({
            // Used to bind the lifecycle of cameras to the lifecycle owner
            val cameraProvider: ProcessCameraProvider = cameraProviderFuture.get()

            // Preview
            val preview = Preview.Builder()
                .build()
                .also {
                    it.setSurfaceProvider(viewBinding.viewFinder.surfaceProvider)
                }
            // comment out ImageCapture and ImageAnalyzer use cases
            imageCapture = ImageCapture.Builder().build()

            val imageAnalyzer = ImageAnalysis.Builder()
                .build()
                .also {
                    it.setAnalyzer(cameraExecutor, LuminosityAnalyzer { luma ->
                        // viewBinding.solutionL.apply {
                        //     this.setBackgroundColor(argbC[3]); text = answerL
                        // } // NG for View
                        // println(answerL); // Log.d(TAG, answerL)
                        dispVal(nRow*nCol+1) // OK for Button
                    })
                }

            // Select back camera as a default
            val cameraSelector = CameraSelector.DEFAULT_BACK_CAMERA

            try {
                // Unbind use cases before rebinding
                cameraProvider.unbindAll()

                // Bind use cases to camera
                cameraProvider.bindToLifecycle(
                    this, cameraSelector, preview, imageCapture, imageAnalyzer
                ) // , videoCapture)

            } catch (exc: Exception) {
                Log.e(TAG, "Use case binding failed", exc)
            }

        }, ContextCompat.getMainExecutor(this))
    }

    private fun stopCamera() {
        val cameraProviderFuture = ProcessCameraProvider.getInstance(this)
        cameraProviderFuture.addListener({
            // Used to unbind the lifecycle of cameras to the lifecycle owner
            val cameraProvider: ProcessCameraProvider = cameraProviderFuture.get()
            cameraProvider.unbindAll()
        }, ContextCompat.getMainExecutor(this))
    }

    private fun allPermissionsGranted() = REQUIRED_PERMISSIONS.all {
        ContextCompat.checkSelfPermission(
            baseContext, it) == PackageManager.PERMISSION_GRANTED
    }

    override fun onDestroy() {
        super.onDestroy()
        cameraExecutor.shutdown()
    }

    companion object {
        private const val TAG = "LitmusPaperReader"
        private const val FILENAME_FORMAT = "yyyy-MM-dd-HH-mm-ss-SSS"
        private const val REQUEST_CODE_PERMISSIONS = 10
        private val REQUIRED_PERMISSIONS =
            mutableListOf (
                Manifest.permission.CAMERA,
                Manifest.permission.RECORD_AUDIO
            ).apply {
                if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.P) {
                    add(Manifest.permission.WRITE_EXTERNAL_STORAGE)
                }
            }.toTypedArray()
    }

    override fun onRequestPermissionsResult(
        requestCode: Int, permissions: Array<String>, grantResults:IntArray) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults)
        if (requestCode == REQUEST_CODE_PERMISSIONS) {
            if (allPermissionsGranted()) {
                startCamera()
            } else {
                Toast.makeText(this,
                    "Permissions not granted by the user.",
                    Toast.LENGTH_SHORT).show()
                finish()
            }
        }
    }

    private fun dispInfo(infi:Int): Unit {
        if(infi < 0) info = info + 1
        else info = infi
        if (info > 3) info = 0
        var ID = 3
        var answerR = ""
        when (info) {
            0 -> answerR = "Push Blue Button to (S)ave/(O)pen/(C)lose/(-)/(+)." +
                    "\n(-)(+) to change nRow, nCol or gHdp." +
                    "\n(S)ave nRow nCol gHdp gWdp in file ratioRCH.txt." +
                    "\n(O)pen Camera and then (C)lose Camera" +
                    "\nwhen the test strip is placed correctly." +
                    "\ngHdp is the grid Height-spacing in dp." +
                    "\ngWdp (grid Width-spacing) is fixed at ${gWdp}dp."
            1 -> answerR = "ratioRCH.txt is saved in Internal_Storage:" +
                    "\n/Android/data/com.example.camera1/files/" +
                    "\nThe data in this file can be changed." +
                    "\nTouch to display guides/results again."
            2 -> answerR = answerL
            3 -> ID = 7
        }
        viewBinding.solutionL.apply { this.setBackgroundColor(argbC[ID]); text = answerR }
    }

    private fun dispButton():Unit {
        viewBinding.face00Button.apply {
            this.setBackgroundColor(argbC[5]); text = "S"
        }
        viewBinding.face01Button.apply {
            this.setBackgroundColor(argbC[5]); text = "-"
        }
        viewBinding.face02Button.apply {
            this.setBackgroundColor(argbC[6]); text = "${nRow}"
        }
        viewBinding.face03Button.apply {
            this.setBackgroundColor(argbC[5]); text = "+"
        }
        viewBinding.face04Button.apply {
            this.setBackgroundColor(argbC[5]); text = "-"
        }
        viewBinding.face05Button.apply {
            this.setBackgroundColor(argbC[6]); text = "${nCol}"
        }
        viewBinding.face06Button.apply {
            this.setBackgroundColor(argbC[5]); text = "+"
        }
        viewBinding.face07Button.apply {
            this.setBackgroundColor(argbC[5]); text = "-"
        }
        viewBinding.face08Button.apply {
            this.setBackgroundColor(argbC[6]); text = "${gHdp}"
        }
        viewBinding.face09Button.apply {
            this.setBackgroundColor(argbC[5]); text = "+"
        }
        viewBinding.face10Button.apply {
            this.setBackgroundColor(argbC[5]); text = "C"
        }
        return
    }

    private fun dispVal(nVal:Int):Unit {
        viewBinding.face31Button.apply {this.setBackgroundColor(Color.argb(255,R[0],G[0],B[0])); text = "${Hval[0]}"}
        viewBinding.face32Button.apply {this.setBackgroundColor(Color.argb(255,R[1],G[1],B[1])); text = "${Hval[1]}"}
        viewBinding.face33Button.apply {this.setBackgroundColor(Color.argb(255,R[2],G[2],B[2])); text = "${Hval[2]}"}
        viewBinding.face34Button.apply {this.setBackgroundColor(Color.argb(255,R[3],G[3],B[3])); text = "${Hval[3]}"}
        viewBinding.face35Button.apply {this.setBackgroundColor(Color.argb(255,R[4],G[4],B[4])); text = "${Hval[4]}"}
        viewBinding.face36Button.apply {this.setBackgroundColor(Color.argb(255,R[5],G[5],B[5])); text = "${Hval[5]}"}
        viewBinding.face37Button.apply {this.setBackgroundColor(Color.argb(255,R[6],G[6],B[6])); text = "${Hval[6]}"}
        viewBinding.face38Button.apply {this.setBackgroundColor(Color.argb(255,R[7],G[7],B[7])); text = "${Hval[7]}"}
        viewBinding.face39Button.apply {this.setBackgroundColor(Color.argb(255,R[8],G[8],B[8])); text = "${Hval[8]}"}
        viewBinding.face40Button.apply {this.setBackgroundColor(Color.argb(255,R[9],G[9],B[9])); text = "${Hval[9]}"}
        viewBinding.face41Button.apply {this.setBackgroundColor(Color.argb(255,R[10],G[10],B[10])); text = "${Hval[10]}"}
        viewBinding.face42Button.apply {this.setBackgroundColor(Color.argb(255,R[11],G[11],B[11])); text = "${Hval[11]}"}
        viewBinding.face43Button.apply {this.setBackgroundColor(Color.argb(255,R[12],G[12],B[12])); text = "${Hval[12]}"}
        viewBinding.face44Button.apply {this.setBackgroundColor(Color.argb(255,R[13],G[13],B[13])); text = "${Hval[13]}"}
        viewBinding.face45Button.apply {this.setBackgroundColor(Color.argb(255,R[14],G[14],B[14])); text = "${Hval[14]}"}
        viewBinding.face46Button.apply {this.setBackgroundColor(Color.argb(255,R[15],G[15],B[15])); text = "${Hval[15]}"}
        viewBinding.face47Button.apply {this.setBackgroundColor(Color.argb(255,R[16],G[16],B[16])); text = "${Hval[16]}"}
        viewBinding.face48Button.apply {this.setBackgroundColor(Color.argb(255,R[17],G[17],B[17])); text = "${Hval[17]}"}
        viewBinding.face49Button.apply {this.setBackgroundColor(Color.argb(255,R[18],G[18],B[18])); text = "${Hval[18]}"}
        viewBinding.face50Button.apply {this.setBackgroundColor(Color.argb(255,R[19],G[19],B[19])); text = "${Hval[19]}"}
        viewBinding.face51Button.apply {this.setBackgroundColor(Color.argb(255,R[20],G[20],B[20])); text = "${Hval[20]}"}
        viewBinding.face52Button.apply {this.setBackgroundColor(Color.argb(255,R[21],G[21],B[21])); text = "${Hval[21]}"}
        viewBinding.face53Button.apply {this.setBackgroundColor(Color.argb(255,R[22],G[22],B[22])); text = "${Hval[22]}"}
        viewBinding.face54Button.apply {this.setBackgroundColor(Color.argb(255,R[23],G[23],B[23])); text = "${Hval[23]}"}
        viewBinding.face55Button.apply {this.setBackgroundColor(Color.argb(255,R[24],G[24],B[24])); text = "${Hval[24]}"}
        viewBinding.face56Button.apply {this.setBackgroundColor(Color.argb(255,R[25],G[25],B[25])); text = "${Hval[25]}"}
        viewBinding.face57Button.apply {this.setBackgroundColor(Color.argb(255,R[26],G[26],B[26])); text = "${Hval[26]}"}
        viewBinding.face58Button.apply {this.setBackgroundColor(Color.argb(255,R[27],G[27],B[27])); text = "${Hval[27]}"}
        viewBinding.face59Button.apply {this.setBackgroundColor(Color.argb(255,R[28],G[28],B[28])); text = "${Hval[28]}"}
        viewBinding.face60Button.apply {this.setBackgroundColor(Color.argb(255,R[29],G[29],B[29])); text = "${Hval[29]}"}
        return
    }

    private fun changeRow(stpi: Int): Unit {
        dispGrid(7)
        if(stpi == 0) disC = 1 - disC // for test only
        nRow = nRow + stpi
        if(nRow <= 1) nRow = 1
        if(nRow > 15) nRow = 15
        dispGrid(6)
        viewBinding.face02Button.apply {
            this.setBackgroundColor(argbC[6]); text = "${nRow}"
        }
        return
    }

    private fun changeCol(stpi: Int): Unit {
        dispGrid(7)
        nCol = nCol + stpi
        if(nCol <= 1) nCol = 1
        if(nCol > 15) nCol = 15
        dispGrid(6)
        viewBinding.face05Button.apply {
            this.setBackgroundColor(argbC[6]); text = "${nCol}"
        }
        return
    }

    private fun changegHdp(stpi: Int): Unit {
        dispGrid(7)
        gHdp = gHdp + stpi * 5
        if(gHdp <= 10) gHdp = 10
        if(gHdp > 250) gHdp = 250
        dispGrid(6)
        viewBinding.face08Button.apply {
            this.setBackgroundColor(argbC[6]); text = "${gHdp}"
        }
        return
    }

    private fun setCameraON(OnOff:Int): Unit {
        if(OnOff == 0) cameraON = -cameraON
        else cameraON = OnOff
        if (cameraON > 0) {
            startCamera()
            viewBinding.face10Button.apply { text = "C" }
            dispGrid(6); dispInfo(3)
        } else {
            stopCamera()
            viewBinding.face10Button.apply { text = "O" }
            dispGrid(7)
            viewBinding.solutionL.apply {
                this.setBackgroundColor(argbC[3]); text = answerL
            }
        }
        return
    }

    private fun saveRowCol(): Unit {
        val externalStorageVolumes: Array<out File> =
            ContextCompat.getExternalFilesDirs(applicationContext, null)
        val fileratio = File(externalStorageVolumes[0], "ratioRCH.txt")
        answerL = ""
        for (k in 0..7) answerL = answerL + "${ratio[k]} "
        answerL = answerL + "${nRow} ${nCol} ${gHdp} ${gWdp} ${disC}"
        var pixbb = answerL.toByteArray(Charsets.UTF_8)
        fileratio.writeBytes(pixbb) // 1.0 1.0 1.0 1.0 0.5 0.5 0.5 0.5 2 5 50 50 0
        // println("################################## $ratioRCH.txt\n" + answerL)
    }

    private fun dispGrid(ID: Int): Unit {
        if (disC == 0) dispGridc(ID) else dispGridl(ID)
    }

    private fun dispGridc(ID: Int): Unit {
        if (ID == 6) dispInfo(3)
        for (i in 0..nRow+1) {
            answer = "+  +"
            if(i <= nRow && nCol > 1) {for (j in 2..nCol) answer += "  +"}
            var idp = bHdp + gHdp * (nRow - i)
            when (idp) {
                30 -> viewBinding.cross030.apply { this.setTextColor(argbC[ID]); text = answer }
                35 -> viewBinding.cross035.apply { this.setTextColor(argbC[ID]); text = answer }
                40 -> viewBinding.cross040.apply { this.setTextColor(argbC[ID]); text = answer }
                45 -> viewBinding.cross045.apply { this.setTextColor(argbC[ID]); text = answer }
                50 -> viewBinding.cross050.apply { this.setTextColor(argbC[ID]); text = answer }
                55 -> viewBinding.cross055.apply { this.setTextColor(argbC[ID]); text = answer }
                60 -> viewBinding.cross060.apply { this.setTextColor(argbC[ID]); text = answer }
                65 -> viewBinding.cross065.apply { this.setTextColor(argbC[ID]); text = answer }
                70 -> viewBinding.cross070.apply { this.setTextColor(argbC[ID]); text = answer }
                75 -> viewBinding.cross075.apply { this.setTextColor(argbC[ID]); text = answer }
                80 -> viewBinding.cross080.apply { this.setTextColor(argbC[ID]); text = answer }
                85 -> viewBinding.cross085.apply { this.setTextColor(argbC[ID]); text = answer }
                90 -> viewBinding.cross090.apply { this.setTextColor(argbC[ID]); text = answer }
                95 -> viewBinding.cross095.apply { this.setTextColor(argbC[ID]); text = answer }
                100 -> viewBinding.cross100.apply { this.setTextColor(argbC[ID]); text = answer }
                105 -> viewBinding.cross105.apply { this.setTextColor(argbC[ID]); text = answer }
                110 -> viewBinding.cross110.apply { this.setTextColor(argbC[ID]); text = answer }
                //115 -> viewBinding.cross115.apply { this.setTextColor(argbC[ID]); text = answer }
                120 -> viewBinding.cross120.apply { this.setTextColor(argbC[ID]); text = answer }
                //125 -> viewBinding.cross125.apply { this.setTextColor(argbC[ID]); text = answer }
                130 -> viewBinding.cross130.apply { this.setTextColor(argbC[ID]); text = answer }
                135 -> viewBinding.cross135.apply { this.setTextColor(argbC[ID]); text = answer }
                140 -> viewBinding.cross140.apply { this.setTextColor(argbC[ID]); text = answer }
                145 -> viewBinding.cross145.apply { this.setTextColor(argbC[ID]); text = answer }
                150 -> viewBinding.cross150.apply { this.setTextColor(argbC[ID]); text = answer }
                155 -> viewBinding.cross155.apply { this.setTextColor(argbC[ID]); text = answer }
                160 -> viewBinding.cross160.apply { this.setTextColor(argbC[ID]); text = answer }
                165 -> viewBinding.cross165.apply { this.setTextColor(argbC[ID]); text = answer }
                170 -> viewBinding.cross170.apply { this.setTextColor(argbC[ID]); text = answer }
                175 -> viewBinding.cross175.apply { this.setTextColor(argbC[ID]); text = answer }
                180 -> viewBinding.cross180.apply { this.setTextColor(argbC[ID]); text = answer }
                185 -> viewBinding.cross185.apply { this.setTextColor(argbC[ID]); text = answer }
                190 -> viewBinding.cross190.apply { this.setTextColor(argbC[ID]); text = answer }
                195 -> viewBinding.cross195.apply { this.setTextColor(argbC[ID]); text = answer }
                200 -> viewBinding.cross200.apply { this.setTextColor(argbC[ID]); text = answer }
                205 -> viewBinding.cross205.apply { this.setTextColor(argbC[ID]); text = answer }
                210 -> viewBinding.cross210.apply { this.setTextColor(argbC[ID]); text = answer }
                215 -> viewBinding.cross215.apply { this.setTextColor(argbC[ID]); text = answer }
                220 -> viewBinding.cross220.apply { this.setTextColor(argbC[ID]); text = answer }
                225 -> viewBinding.cross225.apply { this.setTextColor(argbC[ID]); text = answer }
                230 -> viewBinding.cross230.apply { this.setTextColor(argbC[ID]); text = answer }
                235 -> viewBinding.cross235.apply { this.setTextColor(argbC[ID]); text = answer }
                240 -> viewBinding.cross240.apply { this.setTextColor(argbC[ID]); text = answer }
                245 -> viewBinding.cross245.apply { this.setTextColor(argbC[ID]); text = answer }
                250 -> viewBinding.cross250.apply { this.setTextColor(argbC[ID]); text = answer }
                255 -> viewBinding.cross255.apply { this.setTextColor(argbC[ID]); text = answer }
                260 -> viewBinding.cross260.apply { this.setTextColor(argbC[ID]); text = answer }
                265 -> viewBinding.cross265.apply { this.setTextColor(argbC[ID]); text = answer }
                270 -> viewBinding.cross270.apply { this.setTextColor(argbC[ID]); text = answer }
                275 -> viewBinding.cross275.apply { this.setTextColor(argbC[ID]); text = answer }
                280 -> viewBinding.cross280.apply { this.setTextColor(argbC[ID]); text = answer }
                285 -> viewBinding.cross285.apply { this.setTextColor(argbC[ID]); text = answer }
                290 -> viewBinding.cross290.apply { this.setTextColor(argbC[ID]); text = answer }
                295 -> viewBinding.cross295.apply { this.setTextColor(argbC[ID]); text = answer }
                300 -> viewBinding.cross300.apply { this.setTextColor(argbC[ID]); text = answer }
                305 -> viewBinding.cross305.apply { this.setTextColor(argbC[ID]); text = answer }
                310 -> viewBinding.cross310.apply { this.setTextColor(argbC[ID]); text = answer }
                315 -> viewBinding.cross315.apply { this.setTextColor(argbC[ID]); text = answer }
                320 -> viewBinding.cross320.apply { this.setTextColor(argbC[ID]); text = answer }
                325 -> viewBinding.cross325.apply { this.setTextColor(argbC[ID]); text = answer }
                330 -> viewBinding.cross330.apply { this.setTextColor(argbC[ID]); text = answer }
                335 -> viewBinding.cross335.apply { this.setTextColor(argbC[ID]); text = answer }
                340 -> viewBinding.cross340.apply { this.setTextColor(argbC[ID]); text = answer }
                345 -> viewBinding.cross345.apply { this.setTextColor(argbC[ID]); text = answer }
                350 -> viewBinding.cross350.apply { this.setTextColor(argbC[ID]); text = answer }
                355 -> viewBinding.cross355.apply { this.setTextColor(argbC[ID]); text = answer }
                360 -> viewBinding.cross360.apply { this.setTextColor(argbC[ID]); text = answer }
                365 -> viewBinding.cross365.apply { this.setTextColor(argbC[ID]); text = answer }
                370 -> viewBinding.cross370.apply { this.setTextColor(argbC[ID]); text = answer }
                375 -> viewBinding.cross375.apply { this.setTextColor(argbC[ID]); text = answer }
                380 -> viewBinding.cross380.apply { this.setTextColor(argbC[ID]); text = answer }
                //385 -> viewBinding.cross385.apply { this.setTextColor(argbC[ID]); text = answer }
                390 -> viewBinding.cross390.apply { this.setTextColor(argbC[ID]); text = answer }
                395 -> viewBinding.cross395.apply { this.setTextColor(argbC[ID]); text = answer }
                400 -> viewBinding.cross400.apply { this.setTextColor(argbC[ID]); text = answer }
                405 -> viewBinding.cross405.apply { this.setTextColor(argbC[ID]); text = answer }
                410 -> viewBinding.cross410.apply { this.setTextColor(argbC[ID]); text = answer }
                //415 -> viewBinding.cross415.apply { this.setTextColor(argbC[ID]); text = answer }
                420 -> viewBinding.cross420.apply { this.setTextColor(argbC[ID]); text = answer }
                //425 -> viewBinding.cross425.apply { this.setTextColor(argbC[ID]); text = answer }
                430 -> viewBinding.cross430.apply { this.setTextColor(argbC[ID]); text = answer }
                435 -> viewBinding.cross435.apply { this.setTextColor(argbC[ID]); text = answer }
                440 -> viewBinding.cross440.apply { this.setTextColor(argbC[ID]); text = answer }
                445 -> viewBinding.cross445.apply { this.setTextColor(argbC[ID]); text = answer }
                450 -> viewBinding.cross450.apply { this.setTextColor(argbC[ID]); text = answer }
                //455 -> viewBinding.cross455.apply { this.setTextColor(argbC[ID]); text = answer }
                460 -> viewBinding.cross460.apply { this.setTextColor(argbC[ID]); text = answer }
                465 -> viewBinding.cross465.apply { this.setTextColor(argbC[ID]); text = answer }
                470 -> viewBinding.cross470.apply { this.setTextColor(argbC[ID]); text = answer }
                //475 -> viewBinding.cross475.apply { this.setTextColor(argbC[ID]); text = answer }
                480 -> viewBinding.cross480.apply { this.setTextColor(argbC[ID]); text = answer }
                //485 -> viewBinding.cross485.apply { this.setTextColor(argbC[ID]); text = answer }
                490 -> viewBinding.cross490.apply { this.setTextColor(argbC[ID]); text = answer }
                495 -> viewBinding.cross495.apply { this.setTextColor(argbC[ID]); text = answer }
                500 -> viewBinding.cross500.apply { this.setTextColor(argbC[ID]); text = answer }
                505 -> viewBinding.cross505.apply { this.setTextColor(argbC[ID]); text = answer }
                510 -> viewBinding.cross510.apply { this.setTextColor(argbC[ID]); text = answer }
                //515 -> viewBinding.cross515.apply { this.setTextColor(argbC[ID]); text = answer }
                520 -> viewBinding.cross520.apply { this.setTextColor(argbC[ID]); text = answer }
            }
        }
    }

    private fun dispGridl(ID: Int): Unit {
        if (nCol%2 > 0) {
            if (nCol >= 1) {
                viewBinding.lineV05.apply { this.setBackgroundColor(argbC[ID]) }
                viewBinding.lineV06.apply { this.setBackgroundColor(argbC[ID]) }
            }
            if (nCol >= 2) viewBinding.lineV14.apply { this.setBackgroundColor(argbC[ID]) }
            if (nCol >= 3) viewBinding.lineV17.apply { this.setBackgroundColor(argbC[ID]) }
            if (nCol >= 4) viewBinding.lineV13.apply { this.setBackgroundColor(argbC[ID]) }
            if (nCol >= 5) viewBinding.lineV18.apply { this.setBackgroundColor(argbC[ID]) }
            if (nCol >= 6) viewBinding.lineV12.apply { this.setBackgroundColor(argbC[ID]) }
            if (nCol >= 7) viewBinding.lineV19.apply { this.setBackgroundColor(argbC[ID]) }
            if (nCol >= 8) viewBinding.lineV11.apply { this.setBackgroundColor(argbC[ID]) }
            if (nCol >= 9) viewBinding.lineV20.apply { this.setBackgroundColor(argbC[ID]) }
            if (nCol >=10) viewBinding.lineV10.apply { this.setBackgroundColor(argbC[ID]) }
            if (nCol >=11) viewBinding.lineV21.apply { this.setBackgroundColor(argbC[ID]) }
        } else {
            if (nCol >= 1) {
                viewBinding.lineV35.apply { this.setBackgroundColor(argbC[ID]) }
                viewBinding.lineV36.apply { this.setBackgroundColor(argbC[ID]) }
                viewBinding.lineV46.apply { this.setBackgroundColor(argbC[ID]) }
            }
            if (nCol >= 2) viewBinding.lineV45.apply { this.setBackgroundColor(argbC[ID]) }
            if (nCol >= 2) viewBinding.lineV47.apply { this.setBackgroundColor(argbC[ID]) }
            if (nCol >= 4) viewBinding.lineV44.apply { this.setBackgroundColor(argbC[ID]) }
            if (nCol >= 4) viewBinding.lineV48.apply { this.setBackgroundColor(argbC[ID]) }
            if (nCol >= 6) viewBinding.lineV43.apply { this.setBackgroundColor(argbC[ID]) }
            if (nCol >= 6) viewBinding.lineV49.apply { this.setBackgroundColor(argbC[ID]) }
            if (nCol >= 8) viewBinding.lineV42.apply { this.setBackgroundColor(argbC[ID]) }
            if (nCol >= 8) viewBinding.lineV50.apply { this.setBackgroundColor(argbC[ID]) }
            if (nCol >=10) viewBinding.lineV41.apply { this.setBackgroundColor(argbC[ID]) }
            if (nCol >=10) viewBinding.lineV51.apply { this.setBackgroundColor(argbC[ID]) }
            if (nCol >=12) viewBinding.lineV40.apply { this.setBackgroundColor(argbC[ID]) }
            if (nCol >=12) viewBinding.lineV52.apply { this.setBackgroundColor(argbC[ID]) }
        }
        for (i in 0..nRow + 1) {
            var idp = bHdp + gHdp * (nRow - i)
            when (idp) {
                20 -> viewBinding.lineH020.apply { this.setBackgroundColor(argbC[ID]) }
                25 -> viewBinding.lineH025.apply { this.setBackgroundColor(argbC[ID]) }
                30 -> viewBinding.lineH030.apply { this.setBackgroundColor(argbC[ID]) }
                35 -> viewBinding.lineH035.apply { this.setBackgroundColor(argbC[ID]) }
                40 -> viewBinding.lineH040.apply { this.setBackgroundColor(argbC[ID]) }
                45 -> viewBinding.lineH045.apply { this.setBackgroundColor(argbC[ID]) }
                50 -> viewBinding.lineH050.apply { this.setBackgroundColor(argbC[ID]) }
                55 -> viewBinding.lineH055.apply { this.setBackgroundColor(argbC[ID]) }
                60 -> viewBinding.lineH060.apply { this.setBackgroundColor(argbC[ID]) }
                65 -> viewBinding.lineH065.apply { this.setBackgroundColor(argbC[ID]) }
                70 -> viewBinding.lineH070.apply { this.setBackgroundColor(argbC[ID]) }
                75 -> viewBinding.lineH075.apply { this.setBackgroundColor(argbC[ID]) }
                80 -> viewBinding.lineH080.apply { this.setBackgroundColor(argbC[ID]) }
                85 -> viewBinding.lineH085.apply { this.setBackgroundColor(argbC[ID]) }
                90 -> viewBinding.lineH090.apply { this.setBackgroundColor(argbC[ID]) }
                95 -> viewBinding.lineH095.apply { this.setBackgroundColor(argbC[ID]) }
                100 -> viewBinding.lineH100.apply { this.setBackgroundColor(argbC[ID]) }
                105 -> viewBinding.lineH105.apply { this.setBackgroundColor(argbC[ID]) }
                110 -> viewBinding.lineH110.apply { this.setBackgroundColor(argbC[ID]) }
                //115 -> viewBinding.lineH115.apply { this.setBackgroundColor(argbC[ID]) }
                120 -> viewBinding.lineH120.apply { this.setBackgroundColor(argbC[ID]) }
                //125 -> viewBinding.lineH125.apply { this.setBackgroundColor(argbC[ID]) }
                130 -> viewBinding.lineH130.apply { this.setBackgroundColor(argbC[ID]) }
                135 -> viewBinding.lineH135.apply { this.setBackgroundColor(argbC[ID]) }
                140 -> viewBinding.lineH140.apply { this.setBackgroundColor(argbC[ID]) }
                145 -> viewBinding.lineH145.apply { this.setBackgroundColor(argbC[ID]) }
                150 -> viewBinding.lineH150.apply { this.setBackgroundColor(argbC[ID]) }
                155 -> viewBinding.lineH155.apply { this.setBackgroundColor(argbC[ID]) }
                160 -> viewBinding.lineH160.apply { this.setBackgroundColor(argbC[ID]) }
                165 -> viewBinding.lineH165.apply { this.setBackgroundColor(argbC[ID]) }
                170 -> viewBinding.lineH170.apply { this.setBackgroundColor(argbC[ID]) }
                175 -> viewBinding.lineH175.apply { this.setBackgroundColor(argbC[ID]) }
                180 -> viewBinding.lineH180.apply { this.setBackgroundColor(argbC[ID]) }
                185 -> viewBinding.lineH185.apply { this.setBackgroundColor(argbC[ID]) }
                190 -> viewBinding.lineH190.apply { this.setBackgroundColor(argbC[ID]) }
                195 -> viewBinding.lineH195.apply { this.setBackgroundColor(argbC[ID]) }
                200 -> viewBinding.lineH200.apply { this.setBackgroundColor(argbC[ID]) }
                205 -> viewBinding.lineH205.apply { this.setBackgroundColor(argbC[ID]) }
                210 -> viewBinding.lineH210.apply { this.setBackgroundColor(argbC[ID]) }
                215 -> viewBinding.lineH215.apply { this.setBackgroundColor(argbC[ID]) }
                220 -> viewBinding.lineH220.apply { this.setBackgroundColor(argbC[ID]) }
                225 -> viewBinding.lineH225.apply { this.setBackgroundColor(argbC[ID]) }
                230 -> viewBinding.lineH230.apply { this.setBackgroundColor(argbC[ID]) }
                235 -> viewBinding.lineH235.apply { this.setBackgroundColor(argbC[ID]) }
                240 -> viewBinding.lineH240.apply { this.setBackgroundColor(argbC[ID]) }
                245 -> viewBinding.lineH245.apply { this.setBackgroundColor(argbC[ID]) }
                250 -> viewBinding.lineH250.apply { this.setBackgroundColor(argbC[ID]) }
                255 -> viewBinding.lineH255.apply { this.setBackgroundColor(argbC[ID]) }
                260 -> viewBinding.lineH260.apply { this.setBackgroundColor(argbC[ID]) }
                265 -> viewBinding.lineH265.apply { this.setBackgroundColor(argbC[ID]) }
                270 -> viewBinding.lineH270.apply { this.setBackgroundColor(argbC[ID]) }
                275 -> viewBinding.lineH275.apply { this.setBackgroundColor(argbC[ID]) }
                280 -> viewBinding.lineH280.apply { this.setBackgroundColor(argbC[ID]) }
                285 -> viewBinding.lineH285.apply { this.setBackgroundColor(argbC[ID]) }
                290 -> viewBinding.lineH290.apply { this.setBackgroundColor(argbC[ID]) }
                295 -> viewBinding.lineH295.apply { this.setBackgroundColor(argbC[ID]) }
                300 -> viewBinding.lineH300.apply { this.setBackgroundColor(argbC[ID]) }
                305 -> viewBinding.lineH305.apply { this.setBackgroundColor(argbC[ID]) }
                310 -> viewBinding.lineH310.apply { this.setBackgroundColor(argbC[ID]) }
                315 -> viewBinding.lineH315.apply { this.setBackgroundColor(argbC[ID]) }
                320 -> viewBinding.lineH320.apply { this.setBackgroundColor(argbC[ID]) }
                325 -> viewBinding.lineH325.apply { this.setBackgroundColor(argbC[ID]) }
                330 -> viewBinding.lineH330.apply { this.setBackgroundColor(argbC[ID]) }
                335 -> viewBinding.lineH335.apply { this.setBackgroundColor(argbC[ID]) }
                340 -> viewBinding.lineH340.apply { this.setBackgroundColor(argbC[ID]) }
                345 -> viewBinding.lineH345.apply { this.setBackgroundColor(argbC[ID]) }
                350 -> viewBinding.lineH350.apply { this.setBackgroundColor(argbC[ID]) }
                355 -> viewBinding.lineH355.apply { this.setBackgroundColor(argbC[ID]) }
                360 -> viewBinding.lineH360.apply { this.setBackgroundColor(argbC[ID]) }
                365 -> viewBinding.lineH365.apply { this.setBackgroundColor(argbC[ID]) }
                370 -> viewBinding.lineH370.apply { this.setBackgroundColor(argbC[ID]) }
                375 -> viewBinding.lineH375.apply { this.setBackgroundColor(argbC[ID]) }
                380 -> viewBinding.lineH380.apply { this.setBackgroundColor(argbC[ID]) }
                //385 -> viewBinding.lineH385.apply { this.setBackgroundColor(argbC[ID]) }
                390 -> viewBinding.lineH390.apply { this.setBackgroundColor(argbC[ID]) }
                395 -> viewBinding.lineH395.apply { this.setBackgroundColor(argbC[ID]) }
                400 -> viewBinding.lineH400.apply { this.setBackgroundColor(argbC[ID]) }
                405 -> viewBinding.lineH405.apply { this.setBackgroundColor(argbC[ID]) }
                410 -> viewBinding.lineH410.apply { this.setBackgroundColor(argbC[ID]) }
                //415 -> viewBinding.lineH415.apply { this.setBackgroundColor(argbC[ID]) }
                420 -> viewBinding.lineH420.apply { this.setBackgroundColor(argbC[ID]) }
                //425 -> viewBinding.lineH425.apply { this.setBackgroundColor(argbC[ID]) }
                430 -> viewBinding.lineH430.apply { this.setBackgroundColor(argbC[ID]) }
                435 -> viewBinding.lineH435.apply { this.setBackgroundColor(argbC[ID]) }
                440 -> viewBinding.lineH440.apply { this.setBackgroundColor(argbC[ID]) }
                445 -> viewBinding.lineH445.apply { this.setBackgroundColor(argbC[ID]) }
                450 -> viewBinding.lineH450.apply { this.setBackgroundColor(argbC[ID]) }
                //455 -> viewBinding.lineH455.apply { this.setBackgroundColor(argbC[ID]) }
                460 -> viewBinding.lineH460.apply { this.setBackgroundColor(argbC[ID]) }
                465 -> viewBinding.lineH465.apply { this.setBackgroundColor(argbC[ID]) }
                470 -> viewBinding.lineH470.apply { this.setBackgroundColor(argbC[ID]) }
                //475 -> viewBinding.lineH475.apply { this.setBackgroundColor(argbC[ID]) }
                480 -> viewBinding.lineH480.apply { this.setBackgroundColor(argbC[ID]) }
                //485 -> viewBinding.lineH485.apply { this.setBackgroundColor(argbC[ID]) }
                490 -> viewBinding.lineH490.apply { this.setBackgroundColor(argbC[ID]) }
                495 -> viewBinding.lineH495.apply { this.setBackgroundColor(argbC[ID]) }
                500 -> viewBinding.lineH500.apply { this.setBackgroundColor(argbC[ID]) }
                505 -> viewBinding.lineH505.apply { this.setBackgroundColor(argbC[ID]) }
                510 -> viewBinding.lineH510.apply { this.setBackgroundColor(argbC[ID]) }
                //515 -> viewBinding.lineH515.apply { this.setBackgroundColor(argbC[ID]) }
                520 -> viewBinding.lineH520.apply { this.setBackgroundColor(argbC[ID]) }
            }
        }
    }
}

