XM = {}

function XM.KeepScreen(id)--截屏
    id = id or 0
    releasecapture(id)
    keepcapture(id)
end
KeepScreen = XM.KeepScreen

--分辨率缩放
resolPower = 1	--分辨率系数
function XM.SetScale(mX,mY)	--设置分辨率比例
    local sList = GetScreen()	--当前分辨率
    if mX > mY then	
        local a = mX
        mX = mY
        mY = a
    end
    if sList[1] > sList[2] then
        local a = sList[1]
        sList[1] = sList[2]
        sList[2] = a
    end
    resolPower = sList[1]/mX
end





MyTable = {}
function XM.AddTable(tbl)
    MyTable = tbl
end

function XM.SetTableID(str)
    if MyTable[str] == nil  then
        Print("表名"..tostring(str).."不存在")
    end
    MyTable.ID = str
end



function XM.Find(...)	
    local Arr = {}
    local Rnd ,Str,bool= 5,"",false
    if ... == nil then
        return false
    end
    Arr = {...}
    local iRet, sRet = pcall(function()
    for i = 1,#Arr do
        if type(Arr[i]) == "string" or type(Arr[i]) == "table" then
            Str = Arr[i]
        elseif type(Arr[i]) == "number" then
            Rnd = Arr[i]
        elseif type(Arr[i]) == "boolean" then
            bool = Arr[i]
        end
    end
    local colorList = GetTable(Str)
    if colorList ~= nil then
        if type(colorList[1]) == "table" then
            for i = 1, #colorList do 
                traceprint("当前表:"..colorList[i][1])
                if RndFindColor(Rnd,colorList[i],bool) then
                    return true
                end
            end
            
        else
            if RndFindColor(Rnd,colorList,bool) then
                return true
            end
        end
        
    end
    return false
    end)
    if iRet == true then
        return sRet
    end
    return nil
end


function XM.FindDev(X,Y,Str)		--偏移点击
    local colorList = GetTable(Str)
    if colorList ~= nil then
        if type(colorList[1]) == "table" then
            for i = 1, #colorList do 
                if CoordinateOffsetFindColor(CoorX,CoorY,colorList[i]) then
                    return true
                end
            end
        else
            if CoordinateOffsetFindColor(X,Y,colorList) then
                return true
            end
        end
    end
    return false
end

function XM.FindAllPosition(Str, diff)--返回所有找到的位置  diff:坐标距离
    local iRet, sRet = pcall(function()
    local colorList = GetTable(Str)
    if colorList ~= nil then
        if type(colorList[1]) == "table" then
            colorList = colorList[1]
        end
        local value = CurrencyFindColor(colorList,1)
        if value ~= nil then
            local Arr, List = {}, {}
            Arr = Split(value, "|")
            for i = 1, #Arr do--获取所有相似色点并分割
                List[i] = Split(Arr[i], ",")
            end
            for i = 1, #List do		
                if tonumber(List[i][1]) ~= nil  and tonumber(List[i][2]) ~= nil and tonumber(List[i][3]) ~= nil then
                    local x, y = tonumber(List[i][2]), tonumber(List[i][3])
                    for j = 1, #List do
                        local x1, y1 = tonumber(List[j][2]), tonumber(List[j][3])
                        if i ~= j and List[j][1] ~= "" then
                            if x ~= nil and y ~= nil and x1 ~= nil and y1 ~= nil then
                                local dis = Distance(x, y, x1, y1)
                                if dis < diff then
                                    List[j][1] = ""
                                end
                            else
                                List[j][1] = ""
                            end
                        end
                    end
                end
            end
            local count, RetList = 1, {}
            for i = 1, #List do--去重
                if List[i][1] ~= "" then
                    RetList[count] = List[i]
                    count = count + 1
                end
            end
            return RetList
        end
        
    else
        XM.Print("FindAllPosition:请填写正确的色点名")
        
    end
    return nil
    end)
    if iRet == true then
        return sRet
    else
        Print(sRet)
    end
    return nil
end


function XM.FindNum(Str,bool)	--获取区域指定数量
    bool = bool or false
    local colorList = GetTable(Str)
    if colorList ~= nil then
        if type(colorList[1]) == "table" then
            if FindListAmount(colorList,bool) then
                return true
            end
        else
            if FindAmount(colorList,bool) then
                return true
            end
        end
    end
    return false
end



function CoordinateOffsetFindColor(CoorX, CoorY, Array)--找色偏移点击
    local x,y,value = CurrencyFindColor(Array)
    if(value ~= -1) then
        RndTap(x+CoorX,y+CoorY,1)
        Print("找到:"..Array[1]..",点击:"..x.."-"..y)
        timingColorArr = {}
        return true
    end
    return false
end

switchArr = {}
function XM.Switch(id)			--开关函数
    if(switchArr[id] == nil) then
        switchArr[id] = true
    end
    if(switchArr[id] == true) then
        switchArr[id] = false
        return true
    end
    return false
end
function XM.OpenSwitch(id)	--打开开关
    if id  == nil then
        switchArr = {}
    else
        switchArr[id] = true
    end
    
end






timingColorArr = {}
function XM.TimerColor(id,t)--定时器(找色)
    t = t or 5
    local times = os.time()
    if(timingColorArr[id] == nil) then
        timingColorArr[id] = os.time() + t
    end
    if(timingColorArr[id] <= times) then
        timingColorArr[id] = nil
        return true
    end
    return false
end

timingArr = {}
function XM.Timer(id,t)--定时器
    t = t or 5
    local times = os.time()
    if(timingArr[id] == nil) then
        timingArr[id] = os.time() + t
    end
    if(timingArr[id] <= times) then
        timingArr[id] = nil
        return true
    end
    return false
end
Timer = XM.Timer

function XM.TimerInit(id)	--初始化定时器
    if id  == nil then
        timingArr = {}
    else
        timingArr[id] = nil
    end
end
InitTimer = XM.InitTimer

function XM.TimerRet(id)--返回定时器剩余时间 S	
    if id ~= nil then
        local times = os.time()
        if timingArr[id] == nil or (timingArr[id] - times) <= 0  then
            return 0
        else
            return timingArr[id] - times
        end
    else
        Print("请填写正确的定时器ID")
    end
end

function XM.ReturnDate(t)		--返回天时分
    local str = ""
    local list = {}
    local sList = {"天", "小时", "分", "秒"}
    list[1] = math.floor((t / 60 / 60) / 24)--天 
    list[2] = math.floor((t / 60 / 60) % 24)--时
    list[3] = math.floor((t / 60) % 60)--分
    list[4] = math.floor(t % 60)--秒
    for i = 1, #list do
        if list[i] > 0 then
            str = str .. list[i]..sList[i]
        end
    end
    return str
end

function XM.Msg(str,x,y,t)	--信息框
    x = x or 1
    y = y or 1
    t = t or 2000
    if TimerMsg(str,(t/1000)+0.5) then
        messageboxex(str,t,x,y,1,12)
    end
end


timingMsg = {}
function TimerMsg(id,t)--定时器
    t = t or 5
    local times = os.time()
    if(timingMsg[id] == nil) then
        timingMsg[id] = os.time() + t
        return true
    end
    if(timingMsg[id] <= times) then
        timingMsg[id] = os.time() + t
        return true
    end
    return false
end


function XM.MsgClose()	--关闭信息框
    messageboxex("", 0, 0, 0, 0, 0)
end
MsgClose = XM.MsgClose

function XM.Print(str)--调试输出，可打印表
    level = level or 1
    if type(str) == "table" then	
        PrintTable(str, level)
    else
        traceprint(tostring(str))
    end
end
Print = XM.Print  



function XM.FindRet(Str)
    local colorList = GetTable(Str)
    if colorList ~= nil then
        if type(colorList[1]) == "table" then
            
            for i =1 ,#colorList do
                local list = RetColorXY(colorList[i])
                if list ~= nil then
                    return list
                end
            end
        else
            local list = RetColorXY(colorList)
            if list ~= nil then
                return list
            end
        end
    else
        XM.Print("FindRet参数错误")
    end
    return nil
end

function RetColorXY(Array)
    local list = {-1,-1,-1}
    list[1],list[2],list[3] = CurrencyFindColor(Array)
    if list[1] > -1 then
        return list
    end
    return nil 
end


function RndFindColor(Rnd, Array, bool)
    local x,y,value = CurrencyFindColor(Array)
    if(value > -1) then
        if(bool == true) then
            RndTap(x, y, Rnd)
            Print("找到:"..Array[1]..",点击"..x.."-"..y)
        end
        Print("找到:"..Array[1]..",不点击:"..x.."-"..y)
        timingColorArr = {}
        return true
    end
    return false
end



function XM.RndTap(X, Y, R)--随机点击 X:x坐标 Y:y坐标 R（可选）:随机值
    R = R or 5
    local r1 = rnd(math.abs(R)*-1, math.abs(R))
    local r2 = rnd(math.abs(R)*-1, math.abs(R))
    local r3 = rnd(100,500)
    X,Y = ColorChange(X,Y)
    tap(X + r1, Y + r2)
    Sleep(r3)
    KeepScreen(0)
end


function RndTap(X, Y, R)--随机点击 X:x坐标 Y:y坐标 R（可选）:随机值
    R = R or 5
    R = R or 5
    local r1 = rnd(math.abs(R)*-1, math.abs(R))
    local r2 = rnd(math.abs(R)*-1, math.abs(R))
    local r3 = rnd(100,500)
    tap(X + r1, Y + r2)
    Sleep(r3)
    KeepScreen(0)
end


key = ""
function PrintTable(table, level)--调试输出表
    local indent = ""
    for i = 1, level do
        indent = indent.."  "
    end
    if key ~= "" then
        traceprint(tostring(indent).."["..tostring(key).."]".." ".."=".." ".."{")
    else
        traceprint(tostring(indent) .. "{")
    end
    key = ""
    for k, v in pairs(table) do
        if type(v) == "table" then
            key = k
            PrintTable(v, level + 1)
        else
            local content = string.format("%s[%s] = %s", tostring(indent) .. "  ", tostring(k), tostring(v))
            traceprint(tostring(content))
        end
    end
    traceprint(tostring(indent) .. "}")
end


function XM.Swipe(x1,y1,x2,y2,id,R) --滑动
    R = R or 5
    local r 
    if id == 3 then 
        r = R
    else
        r = rnd(1, R)
    end
    id = id or 1
    x1,y1,x2,y2 = ColorChange(x1,y1,x2,y2)
    if id == 1 then	--随机滑动
        touchdown(x1 + r, y1 + r, 0)
        Sleep(r * 100)
        touchmove(x2 + r, y2 + r, 0)
        Sleep(111)
        touchup(0)
    elseif id == 2 then	--捏合滑动
        local g1, g2
        x1 = x1 + r
        y1 = y1 + r
        x2 = x2 + r
        y2 = y2 + r
        touchdown(x1, y1, 0)
        touchdown(x2, y2, 1)
        g1 = ((x2 - x1) / 2) + x1
        g2 = ((y2 - y1) / 2) + y1
        touchmove(g1, g2, 0)
        touchmove(g1, g2, 1)
        touchup(0)
        touchup(1)
    elseif id == 3 then	--长按滑动
        touchdown(x1, y1, 0)
        Sleep(r)
        touchmove(x2, y2, 0)
        touchup(0)
    end
end



function FindAmount(list,bool)
    local num = getcolornum(list[2],list[3],list[4],list[5],list[6],list[7])
    if num >= list[8] then
        --Print("找色数量为"..tostring(num))
        if bool == true then
            local x = list[4]-((list[4]-list[2])/2)
            local y = list[5]-((list[5]-list[3])/2)
            RndTap(x,y,1)
        end
        return true
    else
        Print("找色数量为"..tostring(num).."小于"..list[8])
        return false
    end
end

function FindListAmount(list,bool)
    for i = 1,#list do
        if FindAmount(list[i],bool) then
            return true
        end
    end
    return false
end


--返回数组[w(宽),h(高),d(dpi)]
function XM.GetScreen()		--获取当前游戏分辨率
    local iRet, sRet = pcall(function()
    local ret = Execute("su -c 'dumpsys window'")
    local info = {}
    _,_,info[3] = ret:find("(%d+)dpi")
    _,_,info[1],info[2],_ = ret:find("app=(%d+)x(%d+)")
    if info[1] then
        info[1] = tonumber(info[1])
        info[2] = tonumber(info[2])
        info[3] = tonumber(info[3])
        return info
    else
        return nil
    end
    end)
    if iRet == true then
        return sRet
    else
        Print(sRet)
        return nil
    end
end
GetScreen = XM.GetScreen

--返回数组[w(宽),h(高),d(dpi)]
function XM.GetScreenSimulator()		--获取当前模拟器分辨率
    local iRet, sRet = pcall(function()
    local ret = Execute("su -c 'dumpsys window'")
    local info = {}
    _,_,info[1],info[2],info[3] = ret:find("init=(%d+)x(%d+) (%d+)dpi")
    if info[1] then
        info[1] = tonumber(info[1])
        info[2] = tonumber(info[2])
        info[3] = tonumber(info[3])
        return info
    else
        return nil
    end
    end)
    if iRet == true then
        return sRet
    else
        Print(sRet)
        return nil
    end
end
GetScreenSimulator = XM.GetScreenSimulator




function XM.Split(Str, cutSymbol)						--字符串分割
    Str = tostring(Str)
    cutSymbol = tostring(cutSymbol)
    if (cutSymbol=='') then 
        return false
    end
    local pos,arr = 0, {}
    for st,sp in function() return string.find(Str, cutSymbol, pos, true) end do
        table.insert(arr, string.sub(Str, pos, st - 1))
        pos = sp + 1
    end
    table.insert(arr, string.sub(Str, pos))
    return arr
end

Split = XM.Split


-------------------------系统---------------------------------------------------------


function XM.GetTap()	--获取点击位置
    Time = 10
    local iRet, sRet = pcall(function()
    local list = GetScreen()
    local ScreenX,ScreenY = tonumber(list[1]),tonumber(list[2])
    local mode = 0
    if ScreenX > ScreenY then
        mode = 1
    end
    local data = Execute("su -c 'getevent -pl'")
    local mList = {}
    local retVlaue = {} 
    if data~=nil then
        _,_,_,_,mList[1]=data:find("ABS_MT_POSITION_X     :+ value (%d*), min (%d*), max (%d*)")
        _,_,_,_,mList[2]=data:find("ABS_MT_POSITION_Y     :+ value (%d*), min (%d*), max (%d*)")
    end
    XM.Print(mList)
    local localpath = TempFile("coor")
    os.execute("su -c 'getevent -l -c "..Time..">"..localpath.."'")
    file=io.open(localpath, "r+");
    value=file:read("*l")
    while value~=nil do
        value=file:read("*l")
        if value~=nil then
            if value:find("ABS_MT_POSITION_X")~=nil then
                local a = tonumber(value:sub(54,62),16)
                if mode == 1 then
                    retVlaue[1]= (ScreenX-math.floor(a*ScreenX/mList[1]))
                else
                    retVlaue[1]= math.floor(a*ScreenX/mList[1])
                end
            elseif value:find("ABS_MT_POSITION_Y")~=nil then
                local b = tonumber(value:sub(54,62),16)
                retVlaue[2]= math.floor(b*ScreenY/mList[2])
            end
            if retVlaue[1] ~= nil and retVlaue[2] ~= nil then
                break
            end
        end
    end
    os.remove(localpath)
    return retVlaue
    end)
    if iRet == true then
        return sRet
    else
        Print(sRet)
        return nil
    end
end



function TempPath()--临时目录
    local tJudge, tValue = pcall(function()
    return getrcpath():match("(.+)/[^/]").."/"
    end)
    if tJudge == true then
        Print("目录获取成功")
        return tValue
    else
        traceprint("临时目录获取失败:"..tostring(tValue))
        return nil
    end
end

function TempFile(fn)
    local tPath = TempPath()
    if tPath == "" then
        return ""
    else
        if fn == nil then
            return tPath .. "TempCmd.txt"
        else
            return tPath .. fn .. ".txt"
        end
    end
end
--执行并返回execute命令的结果[cmd:执行的命令行][返回结果文本]
function Execute(cmdex)
    local iRet, sRet = pcall(function()
    local tFile = TempFile()
    --traceprint("tFile目录："..tFile)
    if tFile == "" then
        return ""
    else
        os.execute("su")
        --cmd = "su -c \'" .. cmd .. " > " .. tFile .."\'"
        --cmd = "" .. cmd .. " > " .. tFile ..""
        cmdex = cmdex.." > " .. tFile
        local ret = os.execute(cmdex)
        return TrimEx(ReadFile(tFile, false), "\r\n ")
    end
    end)
    if iRet == true then
        return sRet
    else
        traceprint(sRet)
        return nil
    end
end

--过滤前导字符[str:要处理的字符串, filt:要过滤的字符]
function LTrimEx(str, filt)
    local iRet, sRet = pcall(function()
    local retstr = ""
    for i = 1, string.len(str) do
        if string.find(filt, string.sub(str, i, i)) == nil then
            retstr = string.sub(str, i, -1)
            break
        end
    end
    return retstr
    end)
    if iRet == true then
        return sRet
    else
        traceprint(sRet)
        return nil
    end
end

--过滤后导字符[str:要处理的字符串, filt:要过滤的字符]
function RTrimEx(str, filt)
    local iRet, sRet = pcall(function()
    local retstr = ""
    for i = string.len(str), 1, -1 do
        if string.find(filt, string.sub(str, i, i)) == nil then
            retstr = string.sub(str, 1, i)
            break
        end
    end
    return retstr
    end)
    if iRet == true then
        return sRet
    else 
        traceprint(sRet)
        return nil
    end
end
--过滤前导与后导字符[str:要处理的字符串, filt:要过滤的字符]
function TrimEx(str, filt)
    local tmpstr
    tmpstr = LTrimEx(str, filt)
    return RTrimEx(tmpstr, filt)
end

--读取文件[path:路径, isdel:是否删除][返回文件内容, 失败返回空字符串]
function ReadFile(path, isdel)
    local iRet, sRet = pcall(function()
    local f = io.open(path, "r")
    if f == nil then
        return ""
    end
    local ret = f:read("*all")
    f:close()
    if isdel then
        os.remove(path)
    end
    return ret
    end)
    if iRet == true then
        return sRet
    else
        traceprint(sRet)
        return nil
    end
end

function CurrencyFindColor(Array,mode) 
    mode = mode or 0
    local x1,y1,x2,y2,color,OffsetPos,sim= 0,0,2000,2000,"","",0.8
    -- local iRet, sRet = pcall(
    -- function()
    if #Array == 3 then
        if type(Array[2]) == "string" then 
            color = Array[2] 
        end
        if type(Array[3]) == "string" then
            OffsetPos = Array[3] 
        end
    elseif #Array == 4 then
        if type(Array[2]) == "number" then 
            sim = Array[2] 
        end
        if type(Array[3]) == "string" then 
            color = Array[3] 
        end
        if type(Array[4]) == "string" then
            OffsetPos = Array[4] 
        end
    elseif #Array == 7 then 
        if type(Array[2]) == "number" then
            x1 = Array[2]
        end
        if type(Array[3]) == "number" then
            y1 = Array[3]
        end
        if type(Array[4]) == "number" then
            x2 = Array[4]
        end
        if type(Array[5]) == "number" then
            y2 = Array[5]
        end
        if type(Array[6]) == "string" then
            color = Array[6]
        end
        if type(Array[7]) == "string" then
            OffsetPos = Array[7]
        end
    elseif #Array == 8 then 
        if type(Array[2]) == "number" then
            sim = Array[2]
        end
        if type(Array[3]) == "number" then
            x1 = Array[3]
        end
        if type(Array[4]) == "number" then
            y1 = Array[4]
        end
        if type(Array[5]) == "number" then
            x2 = Array[5]
        end
        if type(Array[6]) == "number" then
            y2 = Array[6]
        end
        if type(Array[7]) == "string" then
            color = Array[7]
        end
        if type(Array[8]) == "string" then
            OffsetPos = Array[8]
        end
    else
        Print("请填写正确的参数")
        return false
    end
    --Print("RndFindColor222")
    x1,y1, x2,y2 = ColorChange(x1,y1, x2,y2)
    OffsetPos = ColorChange(OffsetPos)
    local x,y,value = -1,-1,-1
    if mode == 0 then
        x, y, value = findmulticolor(x1,y1, x2,y2,color, OffsetPos,sim,0)
        return x,y,value
    elseif mode == 1 then
        value = findmulticolorex(x1, y1,x2, y2,color,OffsetPos,sim, 2)
        return value
    end
    return -1,-1,-1
end


function ColorChange(...)	--色点缩放
    if resolPower == 1 then
        return ...
    else
        if ... == nil then
            return ...
        end
        if type(...) == "table" then
            Arr = ...
        else
            Arr = {...}
        end
        if #Arr == 1 then
            local str = ""
            local list = Split(Arr[1],",")
            for i = 1,#list do
                if str ~= "" then
                    str = str .. ","
                end
                local arr = Split(list[i],"|")
                x = math.ceil(tonumber(arr[1]) * resolPower)
                y = math.ceil(tonumber(arr[2]) * resolPower)
                val = arr[3]
                str = str .. x .. "|" .. y .. "|" .. val 
            end
            return Arr[1]
        elseif #Arr == 4 then
            for g = 1,#Arr do
                if type(Arr[g]) == "number" then
                    Arr[g] = Arr[g] * resolPower
                end
            end
            return Arr[1],Arr[2],Arr[3],Arr[4]
        elseif #Arr == 2 then
            for g = 1,#Arr do
                if type(Arr[g]) == "number" then
                    Arr[g] = Arr[g] * resolPower
                end
            end
            return Arr[1],Arr[2]
        end
        return ...
    end
end


function GetTable(list)	
    local name,str = ""
    if type(list) == "table" then
        str = list[1]
        name = list[2]
    else
        name = list
    end
    if str == nil then
        if MyTable[MyTable.ID] ~= nil  then
            for k,v in pairs(MyTable[MyTable.ID]) do --当前这个表内有几个子表;		
                if v[1] == name then	
                    return v;
                elseif v[1][1] == name then
                    return v;
                end 
            end
        else
            Print("表名"..tostring(MyTable.ID).."不存在")
        end
    else
        if MyTable[str] ~= nil  then
            for k,v in pairs(MyTable[str]) do --当前这个表内有几个子表;		
                if v[1] == name then	
                    return v;
                elseif v[1][1] == name then
                    return v;
                end 
            end
        else
            Print("表名"..tostring(str).."不存在")
        end
    end
    return nil;
end

------------------------------界面--------------
--function XM.GetUI(id)		--无论getselectscheckitemindex的id是否存在,都会返回0
--    local control 
--    control = control or editgettext(id)~= "error"
--    control = control or getselectscheckitemindex(id) ~= -1
--    control = control or checkgetselected(id) ~= -1
--    return control
--end

function Distance(x,y,x1,y1)								--距离
    return 	math.abs(math.ceil(math.sqrt((math.pow((x - x1),2)+math.pow((y - y1),2)))))
end

return XM