package com.example.drievka

import android.content.Context
import android.graphics.*
import android.graphics.Color.*
import android.util.AttributeSet
import android.util.Log
import android.view.MotionEvent
import android.view.View
import kotlinx.android.synthetic.main.hra1.view.*
import java.util.*
import kotlin.concurrent.schedule


class Playground(internal var context: Context, attrs: AttributeSet)
    : View(context, attrs) {

    var pwidth = 0F
    var pheight = 0F
    var partOfWidthX = 0.9F
    var partOfHeightY = 0.3F
    var partOfWidthRad = 100
    var partOfHeightRad = 7.5f
    val STROKE_WIDTH = 5f
    var shapesCounter = 0
    var sticksCounter = 0
    var sticksTask = 0
    var shapesTask = 0
    val round = 20F
    lateinit var rectF: Stick
    var sticks = emptyList<Stick>().toMutableList()
    val TAG = "STICK"
    var paintFill = Paint()
    var paintStroke = Paint()
    var selectedPaintStroke = Paint()
    var index = -1
    var firstPointer = -1
    var secondPointer = -1
    var bitmapBin: Bitmap
    var bitmapX = 0F
    var bitmapY = 0F
    var canvRectF = RectF()
    var debagRectF = RectF()
    var debagMode = false
    var anglesList = arrayListOf(0f, 30f, 270f, 330f)
    var rotatedSticks = emptyList<Stick>().toMutableList()
    var transparentPaintFill = Paint()
    var transparentPaintStroke = Paint()
    var bitmapRotation: Bitmap
    var rectRotation = RectF()
    var mat = Matrix()
    var clearSelected = false
    var idStick = 1
    var gridOfSticks = emptyList<Stick>().toMutableList()
    var selectedSticks = emptyList<Stick>().toMutableList()
    var arrayOfShape = emptyList<List<Stick>>().toMutableList()
    var shape = emptyList<Stick>().toMutableList()
    var square = true
    var forRemove = emptyList<Stick>().toMutableList()


    init {
        var opt = BitmapFactory.Options()
        opt.inMutable = true
        bitmapBin = BitmapFactory.decodeResource(
            context.resources,
            android.R.drawable.ic_menu_delete,
            opt
        )
        val resizedBitmap = Bitmap.createScaledBitmap(
            bitmapBin, 200, 250, false
        )
        bitmapBin = resizedBitmap
        bitmapRotation = BitmapFactory.decodeResource(
            context.resources,
            android.R.drawable.ic_menu_rotate,
            opt
        )

        paintFill = Paint().apply {
            style = Paint.Style.FILL
            color = YELLOW
            textSize = 100F
        }
        paintStroke = Paint().apply {
            style = Paint.Style.STROKE
            color = BLACK
            strokeWidth = STROKE_WIDTH
            textSize = 100F
        }
        selectedPaintStroke = Paint().apply {
            style = Paint.Style.STROKE
            color = RED
            strokeWidth = STROKE_WIDTH
            textSize = 100F
        }
        transparentPaintFill = Paint().apply {
            style = Paint.Style.FILL
            color = YELLOW
            textSize = 100F
        }
        transparentPaintStroke = Paint().apply {
            style = Paint.Style.STROKE
            color = BLACK
            strokeWidth = STROKE_WIDTH
            textSize = 100F
        }
        transparentPaintFill.alpha = 20
        transparentPaintStroke.alpha = 20

    }

    override fun onDraw(canvas: Canvas) {
        super.onDraw(canvas)
        //       Toast.makeText(context, "hello",Toast.LENGTH_SHORT).show()


/*        canvas.drawRoundRect(rectF.getRectF(), round, round, paintFill)
        canvas.drawText(
            "" + number,
            rectF.xRight + rectF.rX,
            rectF.yTop + rectF.rY,
            paintFill
        )


        canvas.drawRoundRect(rectF.getRectF(), round, round, paintStroke)
        canvas.drawText(
            "" + number,
            rectF.xRight + rectF.rX,
            rectF.yTop + rectF.rY,
            paintStroke
        )

        bitmapX = rectF.xRight
        bitmapY = rectF.yBottom + rectF.rY
        canvas.drawBitmap(
            bitmapBin,
            bitmapX,
            bitmapY,
            paintStroke
        )

        var paint = Paint()
        paint.strokeWidth = 30f
        for (i in 0..sticks.size-1){
            Log.d(TAG, sticks[i].toString())
            if(index == i) {
                if (sticks[index].rotateMode){
                        rotatedSticks.forEach(){
                        canvas.drawPath(it.getPath(), transparentPaintFill)
                        canvas.drawPath(it.getPath(), transparentPaintStroke)
                            if(debagMode) {
                                paint.setColor(Color.RED)
                                canvas.drawPoint(it.xlt, it.ylt, paint)
                                paint.setColor(Color.MAGENTA)
                                canvas.drawPoint(it.xrt, it.yrt, paint)
                                paint.setColor(Color.LTGRAY)
                                canvas.drawPoint(it.xlb, it.ylb, paint)
                                paint.setColor(Color.BLUE)
                                canvas.drawPoint(it.xrb, it.yrb, paint)
                            }
                    }
                }
                canvas.drawPath(sticks[i].getPath(), paintFill)
                canvas.drawPath(sticks[i].getPath(), selectedPaintStroke)
                canvas.drawBitmap(bitmapRotation, sticks[i].xrt + 20, sticks[i].yrt - 50, paintStroke)
            }else{
                canvas.drawPath(sticks[i].getPath(), paintFill)
                canvas.drawPath(sticks[i].getPath(), paintStroke)
            }
            if(debagMode) {
                paint.setColor(Color.RED)
                canvas.drawPoint(sticks[i].xlt, sticks[i].ylt, paint)
                paint.setColor(Color.MAGENTA)
                canvas.drawPoint(sticks[i].xrt, sticks[i].yrt, paint)
                paint.setColor(Color.LTGRAY)
                canvas.drawPoint(sticks[i].xlb, sticks[i].ylb, paint)
                paint.setColor(Color.BLUE)
                canvas.drawPoint(sticks[i].xrb, sticks[i].yrb, paint)
            }
        }

//        debagRectF = RectF(rectF.getRectF())

        if (!debagRectF.isEmpty) {
            var m = Matrix()
            m.setTranslate(-500f, 0f)
            debagRectF.transform(m)
//            m.mapRect(debagRectF)

            anglesList.forEach { x ->
                m.reset()
                m.setTranslate(-500f, 0f)
                m.setRotate(x, debagRectF.centerX(), debagRectF.centerY())
//                var r = RectF(debagRectF)
                var p = Path()
                p.addRoundRect(debagRectF, round, round, Path.Direction.CW)
                p.transform(m)
                canvas.drawPath(p, transparentPaintFill)
                canvas.drawPath(p, transparentPaintStroke)
            }
            canvas.drawRoundRect(debagRectF, round, round, paintFill)
            canvas.drawRoundRect(debagRectF, round, round, paintStroke)
        }
*/
        var i = 0
        gridOfSticks.forEach {
            if(!it.selected) {
                canvas.drawPath(it.getPath(), transparentPaintFill)
                canvas.drawPath(it.getPath(), transparentPaintStroke)
//                canvas.drawText(it.id, it.centerX, it.centerY, selectedPaintStroke)
                //           canvas.drawText("" +i, it.centerX, it.centerY, paintStroke)
//                if(it.angle == 30f) {
//                    canvas.drawRoundRect(
//                        it.xrb, it.yrb - it.rX*3, it.xrb + 3*it.rX, it.yrb + it.rX*3,
//                        round,
//                        round,
//                        selectedPaintStroke
//                    )
//                }
            }else{
                if(it.inShape){
                    canvas.drawPath(it.getPath(), paintFill)
                    canvas.drawPath(it.getPath(), selectedPaintStroke)
                }else {
                    Log.d(TAG, "SELECTED TRUE")
                    canvas.drawPath(it.getPath(), paintFill)
                    canvas.drawPath(it.getPath(), paintStroke)
                }
            }
            i++
        }



    }

    override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec)
        pwidth = widthMeasureSpec.toFloat()
        pheight = heightMeasureSpec.toFloat()
    }

    override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {
        Log.d("STICK", "Width w= " +w + " height h=" + h)
        super.onSizeChanged(w, h, oldw, oldh)
        pwidth = w.toFloat()
        pheight = h.toFloat()
        val xx = pwidth * partOfWidthX
        val yy = pheight * partOfHeightY
//        var radY = pheight / partOfHeightRad
//        val radX = pwidth / partOfWidthRad

        var cellLength = pheight / 3f

        Log.d(TAG, "cellL= " + cellLength)
        var radY = cellLength * 0.8f / 2
        var radX = cellLength * 0.11f /2

        Log.d(TAG, "rX= " + radX + " rY= " + radY)


        var cell = radX*4 + radY*2

        var col = (pwidth / cellLength).toInt()
        var row = (pheight / cellLength).toInt()

//        while(row < 3){
//            partOfHeightRad += 0.5f
//            radY = pheight / partOfHeightRad
//            cell = radX*4 + radY*2
//
//            col = (pwidth / cell).toInt()
//            row = (pheight / cell).toInt()
//        }
        rectF = Stick(context, xx - radX, yy - radY, xx + radX, yy + radY, radX, radY, "0")
        canvRectF = RectF(0F, 0F, pwidth, pheight)
        if(square) {
            var startX = (pwidth - (cellLength * (col - 0.35f))) / 2f
            if (startX < 10) {
                col -= 1
                startX = (pwidth - (cellLength * (col -0.35f))) / 2f
            }

            var startY = (pheight - (cellLength * (row - 0.2f))) / 2f
            createRectGrid(row,col,radX, radY, startX, startY)
        }else{
            var startX = (pwidth - (cellLength * (col + 0.5f))) / 2f
            if (startX < 30) {
                col -= 1
                startX = (pwidth - (cellLength * (col + 0.5f))) / 2f
            }

            var startY = (pheight - (cellLength * (row - 0.25f))) / 2f

            createTriangleGrid(row, col, radX, radY, startX, startY)

        }

//        var startY = ((pheight - cell*row) - radX*2)/ 2
//        var startX = ((pwidth - cell*col)  - radX*2)/ 2



        addNeighbours()
    }

    private fun addNeighbours() {
        gridOfSticks.forEach { it ->
            if(it.angle == 270f){
//                Log.d(TAG, "ANGLE = 270"  )
                if(!square){
                    gridOfSticks.forEach { neighbor ->
                        if(it != neighbor) {
//                            if (neighbor.xrb == it.xlt && neighbor.yrb == it.ylt){
                            if( neighbor.angle == 30f) {
                                var x1 = it.xlt
                                var x2 = neighbor.xrb
                                var y1 = it.ylt
                                var y2 = neighbor.yrb
//                                Log.d(TAG, "DISTANCE = " + Math.sqrt(
//                                    Math.pow(
//                                        (x1.toDouble() - x2),
//                                        2.0
//                                    ) + Math.pow((y1.toDouble() - y2), 2.0)
//                                ))
                                if (Math.sqrt(
                                        Math.pow(
                                            (x1.toDouble() - x2),
                                            2.0
                                        ) + Math.pow((y1.toDouble() - y2), 2.0)
                                    ) < 7
                                ) {
                                    it.upper = neighbor
//                            }else if(neighbor.xrt == it.xlb && neighbor.yrt == it.ylb){
                                }
                            }
                            if( neighbor.angle == 330f) {
                                var x1 = it.xlb
                                var x2 = neighbor.xrt
                                var y1 = it.ylb
                                var y2 = neighbor.yrt
                                if (Math.sqrt(
                                        Math.pow(
                                            (x2.toDouble() - x1),
                                            2.0
                                        ) + Math.pow((y2.toDouble() - y1), 2.0)
                                    ) < 7
                                ) {
                                    it.lower = neighbor
                                }
                            }
                            if( neighbor.angle == 270f ){
                                var rightRect = RectF(it.xrt, it.yrt - it.rX, it.xrt + 5*it.rX, it.yrt + it.rX*5)
                                if( rightRect.contains(neighbor.xlt, neighbor.ylt) ){
                                    Log.d(TAG, "APPEND RIGHT it id = " + it.id + " id n = " + neighbor.id)
                                    it.right = neighbor
                                }
                            }
                        }
                    }
                }else{
                    gridOfSticks.forEach { neighbor ->
                        if(it != neighbor) {
                            if (neighbor.angle == 0f) {
                                var x1 = it.xrt
                                var x2 = neighbor.xlb
                                var y1 = it.yrt
                                var y2 = neighbor.ylb
//                                Log.d(TAG, "DISTANCE = " + Math.sqrt(
//                                    Math.pow(
//                                        (x1.toDouble() - x2),
//                                        2.0
//                                    ) + Math.pow((y1.toDouble() - y2), 2.0)
//                                ))
                                if (Math.sqrt(
                                        Math.pow(
                                            (x1.toDouble() - x2),
                                            2.0
                                        ) + Math.pow((y1.toDouble() - y2), 2.0)
                                    ) < 7
                                ) {
                                    it.upper = neighbor
                                } else {
                                    x1 = it.xlb
                                    x2 = neighbor.xrt
                                    y1 = it.ylb
                                    y2 = neighbor.ylt
                                    if (Math.sqrt(
                                            Math.pow(
                                                (x1.toDouble() - x2),
                                                2.0
                                            ) + Math.pow((y1.toDouble() - y2), 2.0)
                                        ) < 7
                                    ) {
                                        it.lower = neighbor
                                    }
                                }
                            }else if ( neighbor.angle == it.angle){
                                var rightRect = RectF(it.xrb, it.yrb - it.rX*3, it.xrb + 3*it.rX, it.yrb + it.rX*3)
                                if( rightRect.contains(neighbor.xlb, neighbor.ylb) ){
                                    it.right = neighbor
                                }
                            }
                        }
                    }
                }
            } else if(it.angle == 30f){
                gridOfSticks.forEach { neighbor ->
                    if(it != neighbor) {
                        if (neighbor.angle == 330f){
                            var x1 = it.xrt
                            var x2 = neighbor.xlt
                            var y1 = it.yrt
                            var y2 = neighbor.ylt
//                                Log.d(TAG, "DISTANCE = " + Math.sqrt(
//                                    Math.pow(
//                                        (x1.toDouble() - x2),
//                                        2.0
//                                    ) + Math.pow((y1.toDouble() - y2), 2.0)
//                                ))
                            if (Math.sqrt(
                                    Math.pow(
                                        (x1.toDouble() - x2),
                                        2.0
                                    ) + Math.pow((y1.toDouble() - y2), 2.0)
                                ) < 7
                            ) {
                                it.rightSecond = neighbor
                                }
                        }else if ( neighbor.angle == it.angle){
                            var rightRect = RectF(it.xrt, it.yrt - it.rX*3, it.xrt + 3*it.rX, it.yrt + it.rX*3)
                            if( rightRect.contains(neighbor.xrb, neighbor.yrb) ){
                                it.right = neighbor
                            }
                        }
                    }
                }
            } else if(it.angle == 330f){
                gridOfSticks.forEach { neighbor ->
                    if(it != neighbor) {
                        if (neighbor.angle == 30f){
                            var x1 = it.xrb
                            var x2 = neighbor.xlb
                            var y1 = it.yrb
                            var y2 = neighbor.ylb
//                                Log.d(TAG, "DISTANCE = " + Math.sqrt(
//                                    Math.pow(
//                                        (x1.toDouble() - x2),
//                                        2.0
//                                    ) + Math.pow((y1.toDouble() - y2), 2.0)
//                                ))
                            if (Math.sqrt(
                                    Math.pow(
                                        (x1.toDouble() - x2),
                                        2.0
                                    ) + Math.pow((y1.toDouble() - y2), 2.0)
                                ) < 7
                            ) {
                                it.rightSecond = neighbor
                            }
                        }else if ( neighbor.angle == it.angle){
                            var rightRect = RectF(it.xrb, it.yrb - it.rX*3, it.xrb + 3*it.rX, it.yrb + it.rX*3)
                            if( rightRect.contains(neighbor.xrt, neighbor.yrt) ){
                                it.right = neighbor
                            }
                        }
                    }
                }
            } else{
                gridOfSticks.forEach { neighbor ->
                    if(it != neighbor) {
                        if (neighbor.angle == 270f){
                            var x1 = it.xrb
                            var x2 = neighbor.xlt
                            var y1 = it.yrb
                            var y2 = neighbor.ylt
//                                Log.d(TAG, "DISTANCE = " + Math.sqrt(
//                                    Math.pow(
//                                        (x1.toDouble() - x2),
//                                        2.0
//                                    ) + Math.pow((y1.toDouble() - y2), 2.0)
//                                ))
                            if (Math.sqrt(
                                    Math.pow(
                                        (x1.toDouble() - x2),
                                        2.0
                                    ) + Math.pow((y1.toDouble() - y2), 2.0)
                                ) < 7
                            ) {
                                it.right = neighbor
                            }
                        }else if ( neighbor.angle == it.angle){
                            var lowerRect = RectF(it.xrb, it.yrb - it.rX*3, it.xrb + 3*it.rX, it.yrb + it.rX*3)
                            if( lowerRect.contains(neighbor.xrt, neighbor.yrt) ){
                                it.lower = neighbor
                            }else{
                                var upperRect = RectF(it.xrt, it.yrt - it.rX*3, it.xrt + 3*it.rX, it.yrt + it.rX*3)
                                if( upperRect.contains(neighbor.xrb, neighbor.yrb) ){
                                    it.upper = neighbor
                                }
                            }
                        }
                    }
                }
            }

/*            var topRect = RectF(it.xlt - it.rX*2, it.ylt - it.rX*2, it.xrt+it.rX*3, it.yrt + it.rX*3)
            var botRect = RectF(it.xlb - it.rX*2, it.ylb - it.rX*2, it.xrb+it.rX*3, it.yrb + it.rX*3)
            gridOfSticks.forEach { neighbor ->
                if(it != neighbor) {
                    var otherTopRect = RectF(
                        neighbor.xlt - it.rX * 2,
                        neighbor.ylt - it.rX * 2,
                        neighbor.xrt + it.rX * 2,
                        neighbor.yrt + it.rX * 2
                    )
                    var otherBotRect = RectF(
                        neighbor.xlb - it.rX * 2,
                        neighbor.ylb - it.rX * 2,
                        neighbor.xrb + it.rX * 2,
                        neighbor.yrb + it.rX * 2
                    )
                    if (RectF.intersects(topRect, otherBotRect) || RectF.intersects(
                            topRect,
                            otherTopRect
                        ) || RectF.intersects(botRect, otherBotRect) || RectF.intersects(
                            botRect,
                            otherTopRect
                        )
                    ) {
                        if (!it.neighborhoods.contains(neighbor)) {
                            it.neighborhoods.add(neighbor)
                            neighbor.neighborhoods.add(it)
                        }
                    }
                }
            }

 */
            Log.d(TAG, "it id = " + it.id + " RIGHT = " + it.right.toString() + " RIGHT SECOND = " + it.rightSecond.toString() + " LEFT Up = " + it.upper + " LEFT DOWN = " + it.lower)
        }


    }


    fun createRectGrid(row: Int, col : Int, radX : Float, radY : Float, startX : Float, startY : Float){
        var stY = startY

//        var horizontalRect = Stick(context, xx - radX, yy - radY, xx + radX, yy + radY, radX, radY, 0)
//        horizontalRect.rotateXY(270f)
        Log.d(TAG, "r = " + row + " c = " + col)
        for(i in 0..row*2){
            var stX = startX
            if(i % 2 == 0){
                stX += radX*2
            }
            for(j in 0..col){
                if (i % 2 == 0 ) {
                    if( j != col){
                        Log.d(TAG, "i%2")
                        var idS = "" + i + 0 + j
                        var newStick = Stick(context, stX, stY, stX+radX*2, stY+radY*2, radX, radY, idS)
                        val path = Path()
                        path.addRoundRect(newStick.getRectF(), round, round, Path.Direction.CW)
                        newStick.setPath(path)
                        newStick.rotate(270f)
                        newStick.moveStarted(newStick.xlt, newStick.ylt)
                        newStick.move(stX, stY)
                        newStick.moveEnded()
                        gridOfSticks.add(newStick)
                    }
//                    startX += radX*2 + radY*2
                }else{
                    var idS = "" + i + 1 + j
                    var newStick = Stick(context, stX, stY, stX+radX*2, stY+radY*2, radX, radY, idS)
                    val path = Path()
                    path.addRoundRect(newStick.getRectF(), round, round, Path.Direction.CW)
                    newStick.setPath(path)
                    gridOfSticks.add(newStick)
//                    startX += radX*2 + radY*2
                }
                stX += radX*2 + radY*2
            }
            if(i %2 ==0){
                stY += radX*2
            }
            else{
                stY += radY*2
            }
        }
    }

    fun createTriangleGrid(row: Int, col : Int, radX : Float, radY : Float, startX : Float, startY : Float){
        var stX = startX
        var stY = startY
        var pov = 2
        var rot30 = false
//        var horizontalRect = Stick(context, xx - radX, yy - radY, xx + radX, yy + radY, radX, radY, 0)
//        horizontalRect.rotateXY(270f)
        Log.d(TAG, "r = " + row + " c = " + col)
        for(i in 0..row){
            var stX1 = stX
            if(i % 2 != 0){
                stX1 += radX*2 + radY
            }
            for(j in 0..col-1){
                var idS = "" + i + 0 + j
                var newStick1 = Stick(context, stX1, stY, stX1+radX*2, stY+radY*2, radX, radY, idS)
                var path1 = Path()
                path1.addRoundRect(newStick1.getRectF(), round, round, Path.Direction.CW)
                newStick1.setPath(path1)
                newStick1.rotate(270f)
                newStick1.moveStarted(newStick1.xlt, newStick1.ylt)
                newStick1.move(stX1, stY)
                newStick1.moveEnded()
                gridOfSticks.add(newStick1)
                if( i != row) {
                    idS = "" + i + 1 + j
                    var newStick2 = Stick(
                        context,
                        newStick1.xlb - radX * 2,
                        newStick1.ylb,
                        newStick1.xlb,
                        newStick1.ylb + radY * 2,
                        radX,
                        radY,
                        idS
                    )
                    var path2 = Path()
                    path2.addRoundRect(newStick2.getRectF(), round, round, Path.Direction.CW)
                    newStick2.setPath(path2)
                    newStick2.rotate(330f)
                    newStick2.moveStarted(newStick2.xlt, newStick2.ylt)
                    newStick2.move(newStick1.xlb - radX * 2, newStick1.ylb + radX)
                    newStick2.moveEnded()
                    gridOfSticks.add(newStick2)
                    idS = "" + i + 2 + j
                    var newStick3 = Stick(
                        context,
                        newStick1.xrb,
                        newStick1.yrb,
                        newStick1.xrb + radX * 2,
                        newStick1.yrb + radY * 2,
                        radX,
                        radY,
                        idS
                    )
                    var path3 = Path()
                    path3.addRoundRect(newStick3.getRectF(), round, round, Path.Direction.CW)
                    newStick3.setPath(path3)
                    newStick3.rotate(30f)
                    newStick3.moveStarted(newStick3.xlt, newStick3.ylt)
                    newStick3.move(newStick1.xrb, newStick1.yrb)
                    newStick3.moveEnded()
                    gridOfSticks.add(newStick3)
                    if(i % 2 != 0 && j == 0){
                        idS = "" + i + 3 + j
                        var newStick4 = Stick(
                            context,
                            newStick2.xlt - radX*2,
                            newStick2.ylt,
                            newStick2.xlt,
                            newStick2.ylt + radY * 2,
                            radX,
                            radY,
                            idS
                        )
                        var path4 = Path()
                        path4.addRoundRect(newStick4.getRectF(), round, round, Path.Direction.CW)
                        newStick4.setPath(path4)
                        newStick4.rotate(30f)
                        newStick4.moveStarted(newStick4.xlt, newStick4.ylt)
                        newStick4.move(newStick2.xlt - radX*2, newStick2.ylt - radX)
                        newStick4.moveEnded()
                        gridOfSticks.add(newStick4)
                    }
                    if(i % 2 == 0 && j == col-1){
                        idS = "" + i + 3 + j
                        var newStick4 = Stick(
                            context,
                            newStick3.xlt,
                            newStick3.ylt,
                            newStick3.xlt + radX*2,
                            newStick3.ylt + radY * 2,
                            radX,
                            radY,
                            idS
                        )

                        var path4 = Path()
                        path4.addRoundRect(newStick4.getRectF(), round, round, Path.Direction.CW)
                        newStick4.setPath(path4)
                        newStick4.rotate(330f)
                        newStick4.moveStarted(newStick4.xlt, newStick4.ylt)
                        newStick4.move(newStick3.xrt, newStick3.yrt)
                        newStick4.moveEnded()
                        gridOfSticks.add(newStick4)
                    }
                }
                stX1 += radX*4 + radY*2
            }
           stY += radX + 2*radY
        }
    }
    override fun onTouchEvent(event: MotionEvent): Boolean {
//        Log.d(
//            TAG, "event.actionMasked " + event.actionMasked +
//                    "event.getPointerId(pointerIndex) " + event.getPointerId(0)
//        )

//        val pointerIndex = event.actionMasked -1
//        val pointerID = event.getPointerId(pointerIndex)
        val x = event.x
        val y = event.y
        when (event.action) {
            MotionEvent.ACTION_DOWN -> {
                return true
            }
            MotionEvent.ACTION_UP -> {
                Log.d(TAG, "EVENT 1")
                gridOfSticks.forEach {
                    if(it.isIn(x,y)){
                        if(it.selected){
                            selectedSticks.remove(it)
                            sticksCounter--
                            removeInArray(it)
                        }else{
                            selectedSticks.add(it)
                            sticksCounter++
                        }
                        it.selected = !it.selected
                        Log.d(TAG, "selected = " + it.selected )
                    }
                }
                invalidate()
 //               if(triangle){
                    countShapes()
//                }else{
//                    countSquare()
//                }
                return true
            }
        }
        return super.onTouchEvent(event)
    }

    private fun removeInArray(stick: Stick) {
        var j = 0
        for(i in 0..arrayOfShape.size-1){
            if(arrayOfShape[j].contains(stick)){
                arrayOfShape.removeAt(j)
                j--
                shapesCounter--
            }
            j++
        }
    }
/*    override fun onTouchEvent(event: MotionEvent): Boolean {
//        Log.d(
//            TAG, "event.actionMasked " + event.actionMasked +
//                    "event.getPointerId(pointerIndex) " + event.getPointerId(0)
//        )

//        val pointerIndex = event.actionMasked -1
//        val pointerID = event.getPointerId(pointerIndex)
        val x = event.x
        val y = event.y
        when (event.actionMasked) {
            0 -> {
//                Toast.makeText(context, " " + paths.size + " " + rects.size, Toast.LENGTH_SHORT).show()

//                Toast.makeText(context, "DOWN: " + sticks.size, Toast.LENGTH_SHORT).show()
                if (rectF.isIn(x, y)) {
                    Toast.makeText(context, "NEW ADDED", Toast.LENGTH_SHORT).show()
                    var newStick = Stick(
                        context, rectF.xLeft, rectF.yTop, rectF.xRight, rectF.yBottom,
                        rectF.rX, rectF.rY, idStick
                    )
                    idStick++
                    newStick.moveStarted(x, y)
                    val path = Path()
                    path.addRoundRect(newStick.getRectF(), round, round, Path.Direction.CW)
                    newStick.setPath(path)
                    sticks.add(newStick)
                    index = sticks.size - 1
                } else {
                    for (i in 0..sticks.size - 1) {
                        if (sticks[i].isIn(x, y)) {
                            if (i != index){
                                if(index != -1) {
                                    sticks[index].rotateMode = false
                                    rotatedSticks.clear()
                                }
                                index = i
                            }else{
                                clearSelected = true
                                sticks[index].rotateMode = false
                                rotatedSticks.clear()
                            }
                            sticks[index].moveStarted(x, y)
                        }
                    }
                }
                invalidate()
                return true
            }
            2 -> {
                    if (index >= 0) {
//                        Log.d(TAG, "YES" + i )
                        if (canvRectF.contains(
                                sticks[index].xlt + (x - sticks[index].previousEventX),
                                sticks[index].ylt + (y - sticks[index].previousEventY)
                            ) &&
                            canvRectF.contains(
                                sticks[index].xrt + (x - sticks[index].previousEventX),
                                sticks[index].yrt + (y - sticks[index].previousEventY)
                            )
                            &&
                            canvRectF.contains(
                                sticks[index].xlb + (x - sticks[index].previousEventX),
                                sticks[index].ylb + (y - sticks[index].previousEventY)
                            )
                            &&
                            canvRectF.contains(
                                sticks[index].xrb + (x - sticks[index].previousEventX),
                                sticks[index].yrb + (y - sticks[index].previousEventY)
                            )
                        ) {
                            sticks[index].move(x, y)
                        }
                    }
                invalidate()
                return true
            }
            1 -> {
//                Toast.makeText(context, "UP: " + 1, Toast.LENGTH_SHORT).show()
                if (index >= 0) {
                    var clearIndex = true
                    if (sticks[index].isIn(x, y) && sticks[index].moved) {
                        if (checkDel()) {
                            sticks.removeAt(index)
                            rotatedSticks.clear()
                            index = -1
                            // !!!!!!!!!!!!!!NEED CLEAN NEIGHBORS!!!!!!!!!!!!!!
//                            Log.d(TAG, "check true")
                        } else {
//                            Log.d(TAG, "before gravity " + index)
                            sticks[index].rotateMode = false
                            rotatedSticks.clear()
                            sticks[index].moveEnded()
                            gravity()
                            checkNeighbors()
                        }
                        clearIndex = false
                    } else if(!sticks[index].moved){
                        rectRotation.left = sticks[index].xrt + 20
                        rectRotation.top = sticks[index].yrt - 50
                        rectRotation.right = sticks[index].xrt + 20 + bitmapRotation.width
                        rectRotation.bottom = sticks[index].yrt -50 + bitmapRotation.height
                        sticks[index].moveEnded()
                        if (rectRotation.contains(x, y)) {
                            if (sticks[index].rotateMode) {
                                sticks[index].rotateMode = false
                                rotatedSticks.clear()
                            } else {
                                sticks[index].rotateMode = true
                                var i = 0
                                anglesList.forEach { x ->
                                    var newStick = Stick(
                                        context,
                                        sticks[index].getRectF().left,
                                        sticks[index].getRectF().top,
                                        sticks[index].getRectF().right,
                                        sticks[index].getRectF().bottom,
                                        rectF.rX,
                                        rectF.rY,
                                        -1
                                    )
                                    val path = Path()
                                    path.addRoundRect(
                                        newStick.getRectF(),
                                        round,
                                        round,
                                        Path.Direction.CW
                                    )
                                    newStick.setPath(path)
                                    newStick.angle = 0f
                                    newStick.rotate(anglesList[i])
                                    rotatedSticks.add(newStick)
                                    i++
                                }
                                Log.d(TAG, "CLEAR INDEX FALSE")
                                clearIndex = false
                            }
                        }else if (clearSelected && sticks[index].isIn(x,y)){
/*                            sticks[index].rotateMode = false
                            rotatedSticks.clear()
                            index = -1*/
                            clearIndex = true
                        }
                        else if(index != -1 && sticks[index].rotateMode && !sticks[index].isIn(x,y)){
//                            clearSelected = true
                            for(i in 0..rotatedSticks.size-1) {
                                if(rotatedSticks[i].isIn(x,y)){
                                    Log.d(TAG, "i= " + i + " anglesLits= "+anglesList[i])
//                                    Log.d(TAG, "angle old= " + sticks[index].angle + " angle new= "+angleNew)
//                                    sticks[index].angle = anglesList[i]
                                    sticks[index].rotate(anglesList[i])
//                                    clearSelected = false
                                    checkNeighbors()
                                    break
                                }
                            }
//                            if(!clearSelected){
/*                                sticks[index].rotateMode = false
                                rotatedSticks.clear()
                                index = -1*/
                                clearIndex = true
//                            }
                        }
                    }
                    if(clearIndex){
                        if(index > -1 ) {
                            if( !sticks[index].isIn(x,y)) {
                                sticks[index].rotateMode = false
                                sticks[index].moveEnded()
                                index = -1
                            }
                            rotatedSticks.clear()
                        }
                    }
                }
                clearSelected = false
                invalidate()
                return true
            }
        }
        return super.onTouchEvent(event)
    }
*/

/*
    override fun onTouchEvent(event: MotionEvent): Boolean {
//        Log.d(
//            TAG, "event.actionMasked " + event.actionMasked +
//                    "event.getPointerId(pointerIndex) " + event.getPointerId(0)
//        )

//        val pointerIndex = event.actionMasked -1
//        val pointerID = event.getPointerId(pointerIndex)
        val x = event.x
        val y = event.y
        when (event.actionMasked) {
            0 -> {
//                Toast.makeText(context, " " + paths.size + " " + rects.size, Toast.LENGTH_SHORT).show()

//                Toast.makeText(context, "DOWN: " + sticks.size, Toast.LENGTH_SHORT).show()
                if (rectF.isIn(x, y)) {
                    Toast.makeText(context, "NEW ADDED", Toast.LENGTH_SHORT).show()
                    val newStick = Stick(
                        context, rectF.xLeft, rectF.yTop, rectF.xRight, rectF.yBottom,
                        rectF.rX, rectF.rY
                    )
                    newStick.moveStarted(x, y)
                    val path = Path()
                    path.addRoundRect(newStick.getRectF(), round, round, Path.Direction.CW)
                    newStick.setPath(path)
                    sticks.add(newStick)

                    index = sticks.size - 1
                    firstPointer = event.pointerCount - 1
                } else {
                    for (i in 0..sticks.size - 1) {
                        if (sticks[i].isIn(x, y)) {
                            index = i
                            firstPointer = event.pointerCount - 1
                            sticks[i].moveStarted(x, y)
                        }
                    }
                }
                return true
            }
            5 -> {
                Log.d(TAG, "SECOND IN ACTION " + (event.pointerCount - 1))
                if (index >= 0 && sticks[index].isIn(x, y)) {
                    secondPointer = event.pointerCount - 1
                    Log.d(TAG, "SECOND IN IF" + (event.pointerCount - 1))
                    sticks[index].spx = x
                    sticks[index].spy = y
                }
                return true
            }
            2 -> {
                if (secondPointer < 0) {
                    if (index >= 0) {
//                        Log.d(TAG, "YES" + i )
                        if (canvRectF.contains(
                                sticks[index].xlt + (x - sticks[index].previousEventX),
                                sticks[index].ylt + (y - sticks[index].previousEventY)
                            ) &&
                            canvRectF.contains(
                                sticks[index].xrt + (x - sticks[index].previousEventX),
                                sticks[index].yrt + (y - sticks[index].previousEventY)
                            )
                            &&
                            canvRectF.contains(
                                sticks[index].xlb + (x - sticks[index].previousEventX),
                                sticks[index].ylb + (y - sticks[index].previousEventY)
                            )
                            &&
                            canvRectF.contains(
                                sticks[index].xrb + (x - sticks[index].previousEventX),
                                sticks[index].yrb + (y - sticks[index].previousEventY)
                            )
                        ) {
                            sticks[index].move(x, y)
                        }
                    }
                } else {
                    Log.d(TAG, "ELSE")
                    if(firstPointer != -1 && secondPointer != -1) {
                        sticks[index].newfpx = event.getX(event.findPointerIndex(firstPointer))
                        sticks[index].newfpy = event.getY(event.findPointerIndex(firstPointer))
                        sticks[index].newspx = event.getX(event.findPointerIndex(secondPointer))
                        sticks[index].newspy = event.getY(event.findPointerIndex(secondPointer))
                        sticks[index].rotate()
                    }
                }
                invalidate()
                return true
            }
            1 -> {
//                Toast.makeText(context, "UP: " + 1, Toast.LENGTH_SHORT).show()
                if (index >= 0) {
                    if (secondPointer >= 0) {
                        secondPointer = -1
                        firstPointer = -1
                    } else {
                        sticks[index].moveEnded()
                        if (checkDel()) {
                            sticks.removeAt(index)
//                            Log.d(TAG, "check true")
                        } else {
//                            Log.d(TAG, "before gravity " + index)
                            gravity()
                        }
                        index = -1
                    }
                }
                invalidate()
                return true
            }
            6 -> {
//                Toast.makeText(context, "UP: " + 6, Toast.LENGTH_SHORT).show()
                if (index >= 0) {
                    if (event.actionIndex == firstPointer) {
                        firstPointer = secondPointer
                    }
                    if(firstPointer != -1) {
                        sticks[index].previousEventX = event.getX(firstPointer)
                        sticks[index].previousEventY = event.getY(firstPointer)
                    }
                    secondPointer = -1
                }
                return true
            }
        }
        return super.onTouchEvent(event)
    }*/

    private fun checkDel(): Boolean {
        if(index >= 0 ){

            var delRectF = RectF(bitmapX,bitmapY,bitmapX+bitmapBin.width,bitmapY+bitmapBin.height)
            var st = sticks[index]
            if(delRectF.contains(st.xlt, st.ylt) || delRectF.contains(st.xrt, st.yrt) ||
                delRectF.contains(st.xlb, st.ylb) || delRectF.contains(st.xrb, st.yrb)){
                return true
            }
        }
        return false
    }



    fun gravity() {
        var dx = 0f
        var dy = 0f
        var dist = 99999f
//        var indexNeighbor = -1
//        var  i = 0
        sticks.forEach { it ->
            if(it != sticks[index]){
                var res = sticks[index].isNear(it)
//                Log.d(TAG, "" + sticks[index].isNear(it))
                if (res[0] < dist){
                    dist = res[0]
                    dx = res[1]
                    dy = res[2]
//                    indexNeighbor = i
                }
            }
//            i++
        }
        if (dx != 0f || dy != 0f) {
            sticks[index].moveStarted(0f, 0f)
            sticks[index].move(dx,dy)
            sticks[index].moveEnded()
//            sticks[index].neighborhoods.add(sticks[indexNeighbor])
//            sticks[indexNeighbor].neighborhoods.add(sticks[index])
        }


    }

    fun checkNeighbors(){
        deleteNeighbors()
        if (index > -1){
            sticks.forEach { it ->
                if(it != sticks[index]){
                    if(sticks[index].isNeighbor(it)){
                        Log.d(TAG, "ADD NEIGBOR" + sticks[index].id + " " + it.id)
                        it.neighborhoods.add(sticks[index])
                        sticks[index].neighborhoods.add(it)
                    }
                }
            }
            Log.d(TAG, "NEIGHBORS" + sticks[index].neighborhoods.toString())
        }
    }

    fun deleteNeighbors() {
        if (index > -1) {
            sticks[index].neighborhoods.forEach { neighbor ->
                var idN = neighbor.id
                sticks.forEach {
                    if (it == neighbor) {
                        it.neighborhoods.remove(sticks[index])
                    }
                }
            }
            sticks[index].neighborhoods.clear()
        }
    }

    fun activityPaused(){
        if(index >= 0){
            sticks[index].moveEnded()
            sticks[index].rotateMode = false
            rotatedSticks.clear()
            index = -1
            secondPointer = -1
            firstPointer = -1
        }
    }

    fun countShapes() {
        selectedSticks.forEach {
            if (it.angle == 270f) {
//                backtracking(it)
//                shape.clear()
                var baseLength = countBaseLength(it)
                if(!square) {
                    findTriangles(it, baseLength, true)
                    shape.clear()
                    findTriangles(it, baseLength, false)
                    shape.clear()
                }else{
                    findTetragons(it, baseLength)
                    shape.clear()
                }
            }

        }
    }


    private fun findTriangles(it : Stick, count: Int, down : Boolean){
        var baseLength = count
        var firstSideLength = 0
        //               if(it.leftDown != null && selectedSticks.contains(it.leftDown)){
        var left = it.lower
        if(!down) {
            left = it.upper
        }
        while ( left != null && selectedSticks.contains(left) && firstSideLength < baseLength){
            shape.add(left)
            firstSideLength++
            var secondSideLength = 0
            var secondRight = left.rightSecond
            while(secondRight != null && selectedSticks.contains(secondRight) && secondSideLength < firstSideLength){
                secondSideLength++
                shape.add(secondRight)
                forRemove.add(secondRight)
                if(secondSideLength == firstSideLength){
                    addShape(it, secondSideLength)
                }
                secondRight = secondRight.right
            }
            var countTo = forRemove.size
            for(i in 0.. countTo-1){
                shape.remove(forRemove[i])
            }
            forRemove.clear()
            left = left.right
        }
    }



    private fun addShape(stick: Stick, count: Int) {
        var c = count
        var it = stick
        var list = emptyList<Stick>().toMutableList()
        for(i in 0..shape.size-1){
            list.add(shape[i])
        }
        var list2 = emptyList<Stick>().toMutableList()

        for(i in 0..c-1){
            list2.add(it)
            if( it.right != null) {
                it = it.right!!
            }
        }
        c = list2.size
        for (i in 0..list2.size-1){
            c--
            list.add(list2[c])
        }
        if(checkUnique(list)) {
            arrayOfShape.add(list)
            showNew(arrayOfShape.size-1)
            shapesCounter++
        }
    }

    private fun countBaseLength(it: Stick): Int {
        var stick = it
        var count = 1
        while(stick.right != null && selectedSticks.contains(stick.right)){
            count++
            stick = stick.right!!
        }
        return count
    }

    /*   fun backtracking(stick : Stick){
           shape.add(stick)
           stick.neighborhoods.forEach{ neighbor ->
               if(neighbor.selected) {
                   Log.d(TAG, "CALL BACKTRACK")
                   if(!shape.contains(neighbor)) {
                       backtracking(neighbor)
                   }else{
                       if(shape[0] == neighbor) {
                           Log.d(TAG, "CHECK Shape")
                           if(checkShape()){
                               Log.d(TAG, "ADD SHAPE")
                               arrayOfShape.add(shape)
                               showNew()
                           }
                           return
                       }
                   }
               }
           }
           shape.remove(stick)
       }*/

    private fun checkShape(): Boolean {
        return false
    }



 /*   private fun checkShape(): Boolean {
        if(!checkUnique()){
            return false
        }
        var angle = -1f
        var sides = emptyList<List<Stick>>().toMutableList()
        var side = emptyList<Stick>().toMutableList()
        var index = 0
        var countOfSides = 0
        var sideExists = false
        shape.forEach {
            if (!square) {
                if (it.angle != angle) {
                    if (!side.isEmpty()) {
                        sides.add(side)
                        side.clear()
                        countOfSides++
                    }else{
                        for (i in 0.. sides.size-1){
                            if(sides[i][0].angle == it.angle){
                                if(it.xlt )
                            }
                        }
                    }
                    angle = it.angle
                    side.add(it)
                }
                else{}
            }
            else{

            }
        }
        return false
    }*/

/*    private fun checkShape(): Boolean {
        Log.d(TAG, "number of sticks = " + shape.size)
        var equilateral = true
        var lengthOfSide = 0
        var previousLengthOfSide = 0
        var angle = 0f
        var countOfSides = 0
        var first : Stick? = null
        var second : Stick? = null
        var sides = emptyList<List<Stick>>().toMutableList()
        var side = emptyList<Stick>().toMutableList()
        for( i in 0..shape.size-1){
            first = shape[i]
            if( i == shape.size - 1){
                second = shape[0]
            }else{
                second = shape[i+1]
            }
            Log.d(TAG, "angle i" + first.angle + " angle i+1" + second.angle)
            if(first.angle == second.angle){

                lengthOfSide++
            }else{
                countOfSides++
                if(previousLengthOfSide != 0 && previousLengthOfSide != lengthOfSide){
                    equilateral = false
                }else{
                    previousLengthOfSide = lengthOfSide
                    lengthOfSide = 0
                }
            }

        }
        Log.d(TAG, "SIDES= " + countOfSides)
        if(!checkUnique()){
            return false
        }
        if(square && countOfSides == 4){
            return true
        }else if(!square && countOfSides == 3){
            return true
        }
        return false
    }
*/
    private fun checkUnique(list: MutableList<Stick>): Boolean{
        Log.d(TAG, "Array of Shape size = " + arrayOfShape.size)
        arrayOfShape.forEach {
            if(it.size == list.size){
                var different = false
                it.forEach{ elem ->
                    if(!list.contains(elem)){
                        different = true
                    }
                }
                if(!different){
                    return false
                }
            }
            Log.d(TAG, "SHAPE is = " + it.toString())
        }
        return true
    }


    private fun showNew(i: Int) {
        Log.d(TAG, arrayOfShape[i].toString())
        var delay : Long = 500
        arrayOfShape[i].forEach {
            var timerSelect = Timer().schedule(delay) {
                it.inShape = true
                invalidate()
            }
            delay += 300
        }

        var timerShow = Timer("timerShowNew").schedule(2000) {
            arrayOfShape[i].forEach {
                it.inShape = false
            }
            invalidate()
        }
    }
    fun findTetragons(stick: Stick, baseLength: Int) {
        var firstSideLength = 0
        var lower = stick.lower
        var removeSide = emptyList<Stick>().toMutableList()
        while ( lower != null && selectedSticks.contains(lower) && firstSideLength < baseLength){
            shape.add(lower)
            firstSideLength++
            var secondSideLength = 0
            var right = lower.right
            while(right != null && selectedSticks.contains(right) && secondSideLength < firstSideLength ){
                secondSideLength++
                shape.add(right)
                forRemove.add(right)
                var thirdSideLength = 0
                var upper = right.upper
                while(upper != null && selectedSticks.contains(upper) && thirdSideLength < secondSideLength) {
                    thirdSideLength++
                    shape.add(upper)
                    removeSide.add(upper)
                    if (thirdSideLength == secondSideLength && secondSideLength == firstSideLength) {
                        addShape(stick, secondSideLength)
                    }
                    upper = upper.upper
                }
                var countTo = removeSide.size
                for(i in 0.. countTo-1){
                    shape.remove(removeSide[i])
                }
                removeSide.clear()
                right = right.right
            }
            var countTo = forRemove.size
            for(i in 0.. countTo-1){
                shape.remove(forRemove[i])
            }
            forRemove.clear()
            lower = lower.lower
        }

    }

    fun clearPlayground(){
        selectedSticks.forEach {
            it.selected = false
            it.inShape = false
        }
        shape.clear()
        arrayOfShape.clear()
        forRemove.clear()
        selectedSticks.clear()
        shapesCounter = 0
        sticksCounter = 0
        invalidate()
    }

}