private ScreenCoord GetCalculatedOffsetCoord(ScreenCoord coord1)
        {
            ScreenCoord coord;

            if (coord1.orientation == ScreenPoint.SO_Portrait)
            {
                coord = new ScreenCoord(coord1.x + mScreenXOffset, coord1.y + mScreenYOffset, coord1.orientation);
            }
            else
            {
                coord = new ScreenCoord(coord1.x + mScreenYOffset, coord1.y + mScreenXOffset, coord1.orientation);
            }

            return(coord);
        }
        private int MouseInteractSingleCoord(ScreenCoord coord1, int type)
        {
            int         ret;
            ScreenCoord coord = GetCalculatedOffsetCoord(coord1);

            if (mCurrentGameOrientation != coord.orientation)
            {
                ret = MouseInteract(coord.y, mScreenWidth - coord.x, 0, 0, type);
            }
            else
            {
                ret = MouseInteract(coord.x, coord.y, 0, 0, type);
            }

            return(ret);
        }
        public int MouseSwipe(ScreenCoord start, ScreenCoord end)
        {
            int         ret;
            ScreenCoord coordStart = GetCalculatedOffsetCoord(start);
            ScreenCoord coordEnd   = GetCalculatedOffsetCoord(end);

            if (mCurrentGameOrientation != start.orientation)
            {
                ret = MouseInteract(coordStart.y, mScreenWidth - coordStart.x, coordEnd.y, mScreenWidth - coordEnd.x, GameDevice.MOUSE_SWIPE);
            }
            else
            {
                ret = MouseInteract(coordStart.x, coordStart.y, coordEnd.x, coordEnd.y, GameDevice.MOUSE_SWIPE);
            }

            return(ret);
        }
        //
        // Main functions
        //

        // calculate the offset of dump file for
        // retrieving color of the specific point
        private int CalculateOffset(ScreenCoord coord)
        {
            int       offset = 0;
            const int bpp    = 4;

            if (mChatty)
            {
                if (coord.orientation == ScreenPoint.SO_Landscape)
                {
                    Log.D(TAG, "Mapping (" + coord.x + ", " + coord.y +
                          ") to (" + (coord.x + mScreenYOffset) + ", " + (coord.y + mScreenXOffset) + ")");
                }
                else
                {
                    Log.D(TAG, "Mapping (" + coord.x + ", " + coord.y +
                          ") to (" + (coord.x + mScreenXOffset) + ", " + (coord.y + mScreenYOffset) + ")");
                }
            }

            //if Android version is 7.0 or higher, the dump orientation will obey the device status
            if (mCurrentGameOrientation == ScreenPoint.SO_Portrait)
            {
                if (coord.orientation == ScreenPoint.SO_Portrait)
                {
                    offset = (mScreenWidth * (coord.y + mScreenYOffset) + (coord.x + mScreenXOffset)) * bpp;
                }
                else if (coord.orientation == ScreenPoint.SO_Landscape)
                {
                    offset = (mScreenWidth * (coord.x + mScreenYOffset) + (mScreenWidth - (coord.y + mScreenXOffset))) * bpp;
                }
            }
            else
            {
                if (coord.orientation == ScreenPoint.SO_Portrait)
                {
                    offset = (mScreenHeight * (mScreenWidth - (coord.x + mScreenXOffset)) + (coord.y + mScreenYOffset)) * bpp;
                }
                else if (coord.orientation == ScreenPoint.SO_Landscape)
                {
                    offset = (mScreenHeight * (coord.y + mScreenXOffset) + (coord.x + mScreenYOffset)) * bpp;
                }
            }

            return(offset);
        }
        public ScreenColor GetColorOnScreen(int index, ScreenCoord src, bool refresh)
        {
            FileStream dumpFile;
            int        offset, ret = 0;

            byte[] colorInfo = new byte[4];

            offset = CalculateOffset(src);
            ScreenColor dest = new ScreenColor();

            try
            {
                if (refresh)
                {
                    ret = RequestRefresh();
                }

                dumpFile = mDevice.ScreenshotOpen(index);
                if (dumpFile == null)
                {
                    throw new Exception();
                }
                dumpFile.Seek(offset, SeekOrigin.Begin);
                dumpFile.Read(colorInfo, 0, 4);
                dest.r = colorInfo[0];
                dest.g = colorInfo[1];
                dest.b = colorInfo[2];
                dest.t = colorInfo[3];
            }
            catch (IOException e)
            {
                Log.E(TAG, "File operation failed: " + e.ToString());
                throw new JoshGameLibrary20.ScreenshotErrorException("screenshot error", ret);
            }
            catch (ThreadInterruptedException e)
            {
                Log.E(TAG, "File operation aborted by interrupt: " + e.ToString());
                throw e;
            }

            return(dest);
        }
        /**
         * Check if all colors in the array are all in the specific region rect
         * Note that the colors in the array in unordered
         * @param rectLeftTop The LT of rect
         * @param rectRightBottom The RB of rect
         * @param colors The set of {@link ScreenColor} in match
         * @return True if all colors are in the rect. False if at least one color is not in the rect.
         * @throws InterruptedException When interrupted happened usually the signal from script
         * @throws ScreenshotErrorException When screenshot error happened
         */
        public bool ColorsAreInRect(ScreenCoord rectLeftTop, ScreenCoord rectRightBottom, ArrayList colors)
        {
            ArrayList coordList = new ArrayList();
            ArrayList colorsReturned;
            ArrayList checkList = new ArrayList();
            int       colorCount, orientation;
            int       x_start, x_end, y_start, y_end;

            // sanity check
            if (colors == null || rectLeftTop == null || rectRightBottom == null)
            {
                Log.W(TAG, "checkColorIsInRegion: colors cannot be null");
                throw new NullReferenceException("checkColorIsInRegion: colors cannot be null");
            }
            else
            {
                orientation = rectLeftTop.orientation;
                colorCount  = colors.Count;
            }

            if (rectLeftTop.orientation != rectRightBottom.orientation)
            {
                Log.W(TAG, "checkColorIsInRegion: Src and Dest must in same orientation");
                throw new ArgumentException("checkColorIsInRegion: Src and Dest must in same orientation");
            }

            if (colorCount < 1 || colorCount > mMaxColorFinding)
            {
                Log.W(TAG, "checkColorIsInRegion: colors size should be bigger than 0 and smaller than " +
                      mMaxColorFinding);
                throw new ArgumentException("checkColorIsInRegion: colors size should be bigger than 0 and smaller than " +
                                            mMaxColorFinding);
            }

            for (int i = 0; i < colorCount; i++)
            {
                checkList.Add(false);
            }

            if (rectLeftTop.x > rectRightBottom.x)
            {
                x_start = rectRightBottom.x;
                x_end   = rectLeftTop.x;
            }
            else
            {
                x_start = rectLeftTop.x;
                x_end   = rectRightBottom.x;
            }

            if (rectLeftTop.y > rectRightBottom.y)
            {
                y_start = rectRightBottom.y;
                y_end   = rectLeftTop.y;
            }
            else
            {
                y_start = rectLeftTop.y;
                y_end   = rectRightBottom.y;
            }

            for (int x = x_start; x <= x_end; x++)
            {
                for (int y = y_start; y <= y_end; y++)
                {
                    coordList.Add(new ScreenCoord(x, y, orientation));
                }
            }

            if (mChatty)
            {
                Log.D(TAG, "FindColorInRange: now checking total " + coordList.Count + " points");
            }

            colorsReturned = GetMultiColorOnScreen(coordList, true);
            foreach (ScreenColor color in colorsReturned)
            {
                for (int i = 0; i < colorCount; i++)
                {
                    ScreenColor sc = (ScreenColor)colors[i];

                    if ((bool)checkList[i])
                    {
                        continue;
                    }

                    if (ColorCompare(color, sc))
                    {
                        if (mChatty)
                        {
                            Log.D(TAG, "FindColorInRange: Found color " + color.ToString());
                        }
                        checkList.Insert(i, true);
                    }
                }
            }

            foreach (bool b in checkList)
            {
                if (!b)
                {
                    return(false);
                }
            }

            return(true);
        }
 /**
  * Get the color on a screenshot at current index
  * @param src The source coordinate location
  * @param refresh True if we need to take new screenshot before fetching color
  * @return The {@link ScreenColor} of the src coordination
  * @throws InterruptedException When interrupted or error happened
  * @throws ScreenshotErrorException When screenshot error happened
  */
 public ScreenColor GetColorOnScreen(ScreenCoord src, bool refresh)
 {
     return(GetColorOnScreen(mScreenshotCurrentSlot, src, refresh));
 }
 public int MouseUp(ScreenCoord coord)
 {
     return(MouseInteractSingleCoord(coord, GameDevice.MOUSE_RELEASE));
 }
 public int MouseMoveTo(ScreenCoord coord)
 {
     return(MouseInteractSingleCoord(coord, GameDevice.MOUSE_MOVE_TO));
 }
 public int MouseDown(ScreenCoord coord)
 {
     return(MouseInteractSingleCoord(coord, GameDevice.MOUSE_PRESS));
 }
 public int MouseTripleClick(ScreenCoord coord)
 {
     return(MouseInteractSingleCoord(coord, GameDevice.MOUSE_TRIPLE_TAP));
 }
 public int MouseDoubleClick(ScreenCoord coord)
 {
     return(MouseInteractSingleCoord(coord, GameDevice.MOUSE_DOUBLE_TAP));
 }