/*
 * Copyright (C) 2008 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.commands.monkey;

import android.content.ComponentName;
import android.os.SystemClock;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.Surface;

import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.NoSuchElementException;
import java.util.Random;

/**
 * monkey event queue. It takes a script to produce events sample script format:
 *
 * <pre>
 * type= raw events
 * count= 10
 * speed= 1.0
 * start data &gt;&gt;
 * captureDispatchPointer(5109520,5109520,0,230.75429,458.1814,0.20784314,0.06666667,0,0.0,0.0,65539,0)
 * captureDispatchKey(5113146,5113146,0,20,0,0,0,0)
 * captureDispatchFlip(true)
 * ...
 * </pre>
 */
public class MonkeySourceScript implements MonkeyEventSource {
    private int mEventCountInScript = 0; // total number of events in the file

    private int mVerbose = 0;

    private double mSpeed = 1.0;

    private String mScriptFileName;

    private MonkeyEventQueue mQ;

    private static final String HEADER_COUNT = "count=";

    private static final String HEADER_SPEED = "speed=";

    private long mLastRecordedDownTimeKey = 0;

    private long mLastRecordedDownTimeMotion = 0;

    private long mLastExportDownTimeKey = 0;

    private long mLastExportDownTimeMotion = 0;

    private long mLastExportEventTime = -1;

    private long mLastRecordedEventTime = -1;

    // process scripts in line-by-line mode (true) or batch processing mode (false)
    private boolean mReadScriptLineByLine = false;

    private static final boolean THIS_DEBUG = false;

    // a parameter that compensates the difference of real elapsed time and
    // time in theory
    private static final long SLEEP_COMPENSATE_DIFF = 16;

    // if this header is present, scripts are read and processed in line-by-line mode
    private static final String HEADER_LINE_BY_LINE = "linebyline";

    // maximum number of events that we read at one time
    private static final int MAX_ONE_TIME_READS = 100;

    // event key word in the capture log
    private static final String EVENT_KEYWORD_POINTER = "DispatchPointer";

    private static final String EVENT_KEYWORD_TRACKBALL = "DispatchTrackball";

    private static final String EVENT_KEYWORD_ROTATION = "RotateScreen";

    private static final String EVENT_KEYWORD_KEY = "DispatchKey";

    private static final String EVENT_KEYWORD_FLIP = "DispatchFlip";

    private static final String EVENT_KEYWORD_KEYPRESS = "DispatchPress";

    private static final String EVENT_KEYWORD_ACTIVITY = "LaunchActivity";

    private static final String EVENT_KEYWORD_INSTRUMENTATION = "LaunchInstrumentation";

    private static final String EVENT_KEYWORD_WAIT = "UserWait";

    private static final String EVENT_KEYWORD_LONGPRESS = "LongPress";

    private static final String EVENT_KEYWORD_POWERLOG = "PowerLog";

    private static final String EVENT_KEYWORD_WRITEPOWERLOG = "WriteLog";

    private static final String EVENT_KEYWORD_RUNCMD = "RunCmd";

    private static final String EVENT_KEYWORD_TAP = "Tap";

    private static final String EVENT_KEYWORD_PROFILE_WAIT = "ProfileWait";

    private static final String EVENT_KEYWORD_DEVICE_WAKEUP = "DeviceWakeUp";

    private static final String EVENT_KEYWORD_INPUT_STRING = "DispatchString";

    private static final String EVENT_KEYWORD_PRESSANDHOLD = "PressAndHold";

    private static final String EVENT_KEYWORD_DRAG = "Drag";

    private static final String EVENT_KEYWORD_PINCH_ZOOM = "PinchZoom";

    private static final String EVENT_KEYWORD_START_FRAMERATE_CAPTURE = "StartCaptureFramerate";

    private static final String EVENT_KEYWORD_END_FRAMERATE_CAPTURE = "EndCaptureFramerate";

    private static final String EVENT_KEYWORD_START_APP_FRAMERATE_CAPTURE =
            "StartCaptureAppFramerate";

    private static final String EVENT_KEYWORD_END_APP_FRAMERATE_CAPTURE = "EndCaptureAppFramerate";

    // a line at the end of the header
    private static final String STARTING_DATA_LINE = "start data >>";

    private boolean mFileOpened = false;

    private static int LONGPRESS_WAIT_TIME = 2000; // wait time for the long

    private long mProfileWaitTime = 5000; //Wait time for each user profile

    private long mDeviceSleepTime = 30000; //Device sleep time

    FileInputStream mFStream;

    DataInputStream mInputStream;

    BufferedReader mBufferedReader;

    // X and Y coordincates of last touch event. Array Index is the pointerId
    private float mLastX[] = new float[2];

    private float mLastY[] = new float[2];

    private long mScriptStartTime = -1;

    private long mMonkeyStartTime = -1;

    /**
     * Creates a MonkeySourceScript instance.
     *
     * @param filename The filename of the script (on the device).
     * @param throttle The amount of time in ms to sleep between events.
     */
    public MonkeySourceScript(Random random, String filename, long throttle,
            boolean randomizeThrottle, long profileWaitTime, long deviceSleepTime) {
        mScriptFileName = filename;
        mQ = new MonkeyEventQueue(random, throttle, randomizeThrottle);
        mProfileWaitTime = profileWaitTime;
        mDeviceSleepTime = deviceSleepTime;
    }

    /**
     * Resets the globals used to timeshift events.
     */
    private void resetValue() {
        mLastRecordedDownTimeKey = 0;
        mLastRecordedDownTimeMotion = 0;
        mLastRecordedEventTime = -1;
        mLastExportDownTimeKey = 0;
        mLastExportDownTimeMotion = 0;
        mLastExportEventTime = -1;
    }

    /**
     * Reads the header of the script file.
     *
     * @return True if the file header could be parsed, and false otherwise.
     * @throws IOException If there was an error reading the file.
     */
    private boolean readHeader() throws IOException {
        mFileOpened = true;

        mFStream = new FileInputStream(mScriptFileName);
        mInputStream = new DataInputStream(mFStream);
        mBufferedReader = new BufferedReader(new InputStreamReader(mInputStream));

        String line;

        while ((line = mBufferedReader.readLine()) != null) {
            line = line.trim();

            if (line.indexOf(HEADER_COUNT) >= 0) {
                try {
                    String value = line.substring(HEADER_COUNT.length() + 1).trim();
                    mEventCountInScript = Integer.parseInt(value);
                } catch (NumberFormatException e) {
                    Logger.err.println("" + e);
                    return false;
                }
            } else if (line.indexOf(HEADER_SPEED) >= 0) {
                try {
                    String value = line.substring(HEADER_COUNT.length() + 1).trim();
                    mSpeed = Double.parseDouble(value);
                } catch (NumberFormatException e) {
                    Logger.err.println("" + e);
                    return false;
                }
            } else if (line.indexOf(HEADER_LINE_BY_LINE) >= 0) {
                mReadScriptLineByLine = true;
            } else if (line.indexOf(STARTING_DATA_LINE) >= 0) {
                return true;
            }
        }

        return false;
    }

    /**
     * Reads a number of lines and passes the lines to be processed.
     *
     * @return The number of lines read.
     * @throws IOException If there was an error reading the file.
     */
    private int readLines() throws IOException {
        String line;
        for (int i = 0; i < MAX_ONE_TIME_READS; i++) {
            line = mBufferedReader.readLine();
            if (line == null) {
                return i;
            }
            line.trim();
            processLine(line);
        }
        return MAX_ONE_TIME_READS;
    }

     /**
      * Reads one line and processes it.
      *
      * @return the number of lines read
      * @throws IOException If there was an error reading the file.
      */
    private int readOneLine() throws IOException {
        String line = mBufferedReader.readLine();
        if (line == null) {
            return 0;
        }
        line.trim();
        processLine(line);
        return 1;
    }



    /**
     * Creates an event and adds it to the event queue. If the parameters are
     * not understood, they are ignored and no events are added.
     *
     * @param s The entire string from the script file.
     * @param args An array of arguments extracted from the script file line.
     */
    private void handleEvent(String s, String[] args) {
        // Handle key event
        if (s.indexOf(EVENT_KEYWORD_KEY) >= 0 && args.length == 8) {
            try {
                Logger.out.println(" old key\n");
                long downTime = Long.parseLong(args[0]);
                long eventTime = Long.parseLong(args[1]);
                int action = Integer.parseInt(args[2]);
                int code = Integer.parseInt(args[3]);
                int repeat = Integer.parseInt(args[4]);
                int metaState = Integer.parseInt(args[5]);
                int device = Integer.parseInt(args[6]);
                int scancode = Integer.parseInt(args[7]);

                MonkeyKeyEvent e = new MonkeyKeyEvent(downTime, eventTime, action, code, repeat,
                        metaState, device, scancode);
                Logger.out.println(" Key code " + code + "\n");

                mQ.addLast(e);
                Logger.out.println("Added key up \n");
            } catch (NumberFormatException e) {
            }
            return;
        }

        // Handle trackball or pointer events
        if ((s.indexOf(EVENT_KEYWORD_POINTER) >= 0 || s.indexOf(EVENT_KEYWORD_TRACKBALL) >= 0)
                && args.length == 12) {
            try {
                long downTime = Long.parseLong(args[0]);
                long eventTime = Long.parseLong(args[1]);
                int action = Integer.parseInt(args[2]);
                float x = Float.parseFloat(args[3]);
                float y = Float.parseFloat(args[4]);
                float pressure = Float.parseFloat(args[5]);
                float size = Float.parseFloat(args[6]);
                int metaState = Integer.parseInt(args[7]);
                float xPrecision = Float.parseFloat(args[8]);
                float yPrecision = Float.parseFloat(args[9]);
                int device = Integer.parseInt(args[10]);
                int edgeFlags = Integer.parseInt(args[11]);

                MonkeyMotionEvent e;
                if (s.indexOf("Pointer") > 0) {
                    e = new MonkeyTouchEvent(action);
                } else {
                    e = new MonkeyTrackballEvent(action);
                }

                e.setDownTime(downTime)
                        .setEventTime(eventTime)
                        .setMetaState(metaState)
                        .setPrecision(xPrecision, yPrecision)
                        .setDeviceId(device)
                        .setEdgeFlags(edgeFlags)
                        .addPointer(0, x, y, pressure, size);
                mQ.addLast(e);
            } catch (NumberFormatException e) {
            }
            return;
        }

        // Handle trackball or multi-touch  pointer events. pointer ID is the 13th parameter
        if ((s.indexOf(EVENT_KEYWORD_POINTER) >= 0 || s.indexOf(EVENT_KEYWORD_TRACKBALL) >= 0)
                && args.length == 13) {
            try {
                long downTime = Long.parseLong(args[0]);
                long eventTime = Long.parseLong(args[1]);
                int action = Integer.parseInt(args[2]);
                float x = Float.parseFloat(args[3]);
                float y = Float.parseFloat(args[4]);
                float pressure = Float.parseFloat(args[5]);
                float size = Float.parseFloat(args[6]);
                int metaState = Integer.parseInt(args[7]);
                float xPrecision = Float.parseFloat(args[8]);
                float yPrecision = Float.parseFloat(args[9]);
                int device = Integer.parseInt(args[10]);
                int edgeFlags = Integer.parseInt(args[11]);
                int pointerId = Integer.parseInt(args[12]);

                MonkeyMotionEvent e;
                if (s.indexOf("Pointer") > 0) {
                    if (action == MotionEvent.ACTION_POINTER_DOWN) {
                        e = new MonkeyTouchEvent(MotionEvent.ACTION_POINTER_DOWN
                                | (pointerId << MotionEvent.ACTION_POINTER_INDEX_SHIFT))
                                        .setIntermediateNote(true);
                    } else {
                        e = new MonkeyTouchEvent(action);
                    }
                    if (mScriptStartTime < 0) {
                        mMonkeyStartTime = SystemClock.uptimeMillis();
                        mScriptStartTime = eventTime;
                    }
                } else {
                    e = new MonkeyTrackballEvent(action);
                }

                if (pointerId == 1) {
                    e.setDownTime(downTime)
                            .setEventTime(eventTime)
                            .setMetaState(metaState)
                            .setPrecision(xPrecision, yPrecision)
                            .setDeviceId(device)
                            .setEdgeFlags(edgeFlags)
                            .addPointer(0, mLastX[0], mLastY[0], pressure, size)
                            .addPointer(1, x, y, pressure, size);
                    mLastX[1] = x;
                    mLastY[1] = y;
                } else if (pointerId == 0) {
                    e.setDownTime(downTime)
                            .setEventTime(eventTime)
                            .setMetaState(metaState)
                            .setPrecision(xPrecision, yPrecision)
                            .setDeviceId(device)
                            .setEdgeFlags(edgeFlags)
                            .addPointer(0, x, y, pressure, size);
                     if(action == MotionEvent.ACTION_POINTER_UP) {
                         e.addPointer(1, mLastX[1], mLastY[1]);
                     }
                     mLastX[0] = x;
                     mLastY[0] = y;
                }

                // Dynamically adjust waiting time to ensure that simulated evnets follow
                // the time tap specified in the script
                if (mReadScriptLineByLine) {
                    long curUpTime = SystemClock.uptimeMillis();
                    long realElapsedTime = curUpTime - mMonkeyStartTime;
                    long scriptElapsedTime = eventTime - mScriptStartTime;
                    if (realElapsedTime < scriptElapsedTime) {
                        long waitDuration = scriptElapsedTime - realElapsedTime;
                        mQ.addLast(new MonkeyWaitEvent(waitDuration));
                    }
                }
                mQ.addLast(e);
            } catch (NumberFormatException e) {
            }
            return;
        }

        // Handle screen rotation events
        if ((s.indexOf(EVENT_KEYWORD_ROTATION) >= 0) && args.length == 2) {
            try {
                int rotationDegree = Integer.parseInt(args[0]);
                int persist = Integer.parseInt(args[1]);
                if ((rotationDegree == Surface.ROTATION_0) ||
                    (rotationDegree == Surface.ROTATION_90) ||
                    (rotationDegree == Surface.ROTATION_180) ||
                    (rotationDegree == Surface.ROTATION_270)) {
                    mQ.addLast(new MonkeyRotationEvent(rotationDegree,
                                                       persist != 0));
                }
            } catch (NumberFormatException e) {
            }
            return;
        }

        // Handle tap event
        if ((s.indexOf(EVENT_KEYWORD_TAP) >= 0) && args.length >= 2) {
            try {
                float x = Float.parseFloat(args[0]);
                float y = Float.parseFloat(args[1]);
                long tapDuration = 0;
                if (args.length == 3) {
                    tapDuration = Long.parseLong(args[2]);
                }

                // Set the default parameters
                long downTime = SystemClock.uptimeMillis();
                MonkeyMotionEvent e1 = new MonkeyTouchEvent(MotionEvent.ACTION_DOWN)
                        .setDownTime(downTime)
                        .setEventTime(downTime)
                        .addPointer(0, x, y, 1, 5);
                mQ.addLast(e1);
                if (tapDuration > 0){
                    mQ.addLast(new MonkeyWaitEvent(tapDuration));
                }
                MonkeyMotionEvent e2 = new MonkeyTouchEvent(MotionEvent.ACTION_UP)
                        .setDownTime(downTime)
                        .setEventTime(downTime)
                        .addPointer(0, x, y, 1, 5);
                mQ.addLast(e2);
            } catch (NumberFormatException e) {
                Logger.err.println("// " + e.toString());
            }
            return;
        }

        //Handle the press and hold
        if ((s.indexOf(EVENT_KEYWORD_PRESSANDHOLD) >= 0) && args.length == 3) {
            try {
                float x = Float.parseFloat(args[0]);
                float y = Float.parseFloat(args[1]);
                long pressDuration = Long.parseLong(args[2]);

                // Set the default parameters
                long downTime = SystemClock.uptimeMillis();

                MonkeyMotionEvent e1 = new MonkeyTouchEvent(MotionEvent.ACTION_DOWN)
                        .setDownTime(downTime)
                        .setEventTime(downTime)
                        .addPointer(0, x, y, 1, 5);
                MonkeyWaitEvent e2 = new MonkeyWaitEvent(pressDuration);
                MonkeyMotionEvent e3 = new MonkeyTouchEvent(MotionEvent.ACTION_UP)
                        .setDownTime(downTime + pressDuration)
                        .setEventTime(downTime + pressDuration)
                        .addPointer(0, x, y, 1, 5);
                mQ.addLast(e1);
                mQ.addLast(e2);
                mQ.addLast(e2);

            } catch (NumberFormatException e) {
                Logger.err.println("// " + e.toString());
            }
            return;
        }

        // Handle drag event
        if ((s.indexOf(EVENT_KEYWORD_DRAG) >= 0) && args.length == 5) {
            float xStart = Float.parseFloat(args[0]);
            float yStart = Float.parseFloat(args[1]);
            float xEnd = Float.parseFloat(args[2]);
            float yEnd = Float.parseFloat(args[3]);
            int stepCount = Integer.parseInt(args[4]);

            float x = xStart;
            float y = yStart;
            long downTime = SystemClock.uptimeMillis();
            long eventTime = SystemClock.uptimeMillis();

            if (stepCount > 0) {
                float xStep = (xEnd - xStart) / stepCount;
                float yStep = (yEnd - yStart) / stepCount;

                MonkeyMotionEvent e =
                        new MonkeyTouchEvent(MotionEvent.ACTION_DOWN).setDownTime(downTime)
                                .setEventTime(eventTime).addPointer(0, x, y, 1, 5);
                mQ.addLast(e);

                for (int i = 0; i < stepCount; ++i) {
                    x += xStep;
                    y += yStep;
                    eventTime = SystemClock.uptimeMillis();
                    e = new MonkeyTouchEvent(MotionEvent.ACTION_MOVE).setDownTime(downTime)
                        .setEventTime(eventTime).addPointer(0, x, y, 1, 5);
                    mQ.addLast(e);
                }

                eventTime = SystemClock.uptimeMillis();
                e = new MonkeyTouchEvent(MotionEvent.ACTION_UP).setDownTime(downTime)
                    .setEventTime(eventTime).addPointer(0, x, y, 1, 5);
                mQ.addLast(e);
            }
        }

        // Handle pinch or zoom action
        if ((s.indexOf(EVENT_KEYWORD_PINCH_ZOOM) >= 0) && args.length == 9) {
            //Parse the parameters
            float pt1xStart = Float.parseFloat(args[0]);
            float pt1yStart = Float.parseFloat(args[1]);
            float pt1xEnd = Float.parseFloat(args[2]);
            float pt1yEnd = Float.parseFloat(args[3]);

            float pt2xStart = Float.parseFloat(args[4]);
            float pt2yStart = Float.parseFloat(args[5]);
            float pt2xEnd = Float.parseFloat(args[6]);
            float pt2yEnd = Float.parseFloat(args[7]);

            int stepCount = Integer.parseInt(args[8]);

            float x1 = pt1xStart;
            float y1 = pt1yStart;
            float x2 = pt2xStart;
            float y2 = pt2yStart;

            long downTime = SystemClock.uptimeMillis();
            long eventTime = SystemClock.uptimeMillis();

            if (stepCount > 0) {
                float pt1xStep = (pt1xEnd - pt1xStart) / stepCount;
                float pt1yStep = (pt1yEnd - pt1yStart) / stepCount;

                float pt2xStep = (pt2xEnd - pt2xStart) / stepCount;
                float pt2yStep = (pt2yEnd - pt2yStart) / stepCount;

                mQ.addLast(new MonkeyTouchEvent(MotionEvent.ACTION_DOWN).setDownTime(downTime)
                        .setEventTime(eventTime).addPointer(0, x1, y1, 1, 5));

                mQ.addLast(new MonkeyTouchEvent(MotionEvent.ACTION_POINTER_DOWN
                        | (1 << MotionEvent.ACTION_POINTER_INDEX_SHIFT)).setDownTime(downTime)
                        .addPointer(0, x1, y1).addPointer(1, x2, y2).setIntermediateNote(true));

                for (int i = 0; i < stepCount; ++i) {
                    x1 += pt1xStep;
                    y1 += pt1yStep;
                    x2 += pt2xStep;
                    y2 += pt2yStep;

                    eventTime = SystemClock.uptimeMillis();
                    mQ.addLast(new MonkeyTouchEvent(MotionEvent.ACTION_MOVE).setDownTime(downTime)
                            .setEventTime(eventTime).addPointer(0, x1, y1, 1, 5).addPointer(1, x2,
                                    y2, 1, 5));
                }
                eventTime = SystemClock.uptimeMillis();
                mQ.addLast(new MonkeyTouchEvent(MotionEvent.ACTION_POINTER_UP)
                        .setDownTime(downTime).setEventTime(eventTime).addPointer(0, x1, y1)
                        .addPointer(1, x2, y2));
            }
        }

        // Handle flip events
        if (s.indexOf(EVENT_KEYWORD_FLIP) >= 0 && args.length == 1) {
            boolean keyboardOpen = Boolean.parseBoolean(args[0]);
            MonkeyFlipEvent e = new MonkeyFlipEvent(keyboardOpen);
            mQ.addLast(e);
        }

        // Handle launch events
        if (s.indexOf(EVENT_KEYWORD_ACTIVITY) >= 0 && args.length >= 2) {
            String pkg_name = args[0];
            String cl_name = args[1];
            long alarmTime = 0;

            ComponentName mApp = new ComponentName(pkg_name, cl_name);

            if (args.length > 2) {
                try {
                    alarmTime = Long.parseLong(args[2]);
                } catch (NumberFormatException e) {
                    Logger.err.println("// " + e.toString());
                    return;
                }
            }

            if (args.length == 2) {
                MonkeyActivityEvent e = new MonkeyActivityEvent(mApp);
                mQ.addLast(e);
            } else {
                MonkeyActivityEvent e = new MonkeyActivityEvent(mApp, alarmTime);
                mQ.addLast(e);
            }
            return;
        }

        //Handle the device wake up event
        if (s.indexOf(EVENT_KEYWORD_DEVICE_WAKEUP) >= 0){
            String pkg_name = "com.google.android.powerutil";
            String cl_name = "com.google.android.powerutil.WakeUpScreen";
            long deviceSleepTime = mDeviceSleepTime;

            //Start the wakeUpScreen test activity to turn off the screen.
            ComponentName mApp = new ComponentName(pkg_name, cl_name);
            mQ.addLast(new MonkeyActivityEvent(mApp, deviceSleepTime));

            //inject the special key for the wakeUpScreen test activity.
            mQ.addLast(new MonkeyKeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_0));
            mQ.addLast(new MonkeyKeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_0));

            //Add the wait event after the device sleep event so that the monkey
            //can continue after the device wake up.
            mQ.addLast(new MonkeyWaitEvent(deviceSleepTime + 3000));

            //Insert the menu key to unlock the screen
            mQ.addLast(new MonkeyKeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_MENU));
            mQ.addLast(new MonkeyKeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_MENU));

            //Insert the back key to dismiss the test activity
            mQ.addLast(new MonkeyKeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_BACK));
            mQ.addLast(new MonkeyKeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_BACK));

            return;
        }

        // Handle launch instrumentation events
        if (s.indexOf(EVENT_KEYWORD_INSTRUMENTATION) >= 0 && args.length == 2) {
            String test_name = args[0];
            String runner_name = args[1];
            MonkeyInstrumentationEvent e = new MonkeyInstrumentationEvent(test_name, runner_name);
            mQ.addLast(e);
            return;
        }

        // Handle wait events
        if (s.indexOf(EVENT_KEYWORD_WAIT) >= 0 && args.length == 1) {
            try {
                long sleeptime = Integer.parseInt(args[0]);
                MonkeyWaitEvent e = new MonkeyWaitEvent(sleeptime);
                mQ.addLast(e);
            } catch (NumberFormatException e) {
            }
            return;
        }


        // Handle the profile wait time
        if (s.indexOf(EVENT_KEYWORD_PROFILE_WAIT) >= 0) {
            MonkeyWaitEvent e = new MonkeyWaitEvent(mProfileWaitTime);
            mQ.addLast(e);
            return;
        }

        // Handle keypress events
        if (s.indexOf(EVENT_KEYWORD_KEYPRESS) >= 0 && args.length == 1) {
            String key_name = args[0];
            int keyCode = MonkeySourceRandom.getKeyCode(key_name);
            if (keyCode == KeyEvent.KEYCODE_UNKNOWN) {
                return;
            }
            MonkeyKeyEvent e = new MonkeyKeyEvent(KeyEvent.ACTION_DOWN, keyCode);
            mQ.addLast(e);
            e = new MonkeyKeyEvent(KeyEvent.ACTION_UP, keyCode);
            mQ.addLast(e);
            return;
        }

        // Handle longpress events
        if (s.indexOf(EVENT_KEYWORD_LONGPRESS) >= 0) {
            MonkeyKeyEvent e;
            e = new MonkeyKeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_DPAD_CENTER);
            mQ.addLast(e);
            MonkeyWaitEvent we = new MonkeyWaitEvent(LONGPRESS_WAIT_TIME);
            mQ.addLast(we);
            e = new MonkeyKeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_DPAD_CENTER);
            mQ.addLast(e);
        }

        //The power log event is mainly for the automated power framework
        if (s.indexOf(EVENT_KEYWORD_POWERLOG) >= 0 && args.length > 0) {
            String power_log_type = args[0];
            String test_case_status;

            if (args.length == 1){
                MonkeyPowerEvent e = new MonkeyPowerEvent(power_log_type);
                mQ.addLast(e);
            } else if (args.length == 2){
                test_case_status = args[1];
                MonkeyPowerEvent e = new MonkeyPowerEvent(power_log_type, test_case_status);
                mQ.addLast(e);
            }
        }

        //Write power log to sdcard
        if (s.indexOf(EVENT_KEYWORD_WRITEPOWERLOG) >= 0) {
            MonkeyPowerEvent e = new MonkeyPowerEvent();
            mQ.addLast(e);
        }

        //Run the shell command
        if (s.indexOf(EVENT_KEYWORD_RUNCMD) >= 0 && args.length == 1) {
            String cmd = args[0];
            MonkeyCommandEvent e = new MonkeyCommandEvent(cmd);
            mQ.addLast(e);
        }

        //Input the string through the shell command
        if (s.indexOf(EVENT_KEYWORD_INPUT_STRING) >= 0 && args.length == 1) {
            String input = args[0];
            String cmd = "input text " + input;
            MonkeyCommandEvent e = new MonkeyCommandEvent(cmd);
            mQ.addLast(e);
            return;
        }

        if (s.indexOf(EVENT_KEYWORD_START_FRAMERATE_CAPTURE) >= 0) {
            MonkeyGetFrameRateEvent e = new MonkeyGetFrameRateEvent("start");
            mQ.addLast(e);
            return;
        }

        if (s.indexOf(EVENT_KEYWORD_END_FRAMERATE_CAPTURE) >= 0 && args.length == 1) {
            String input = args[0];
            MonkeyGetFrameRateEvent e = new MonkeyGetFrameRateEvent("end", input);
            mQ.addLast(e);
            return;
        }

        if (s.indexOf(EVENT_KEYWORD_START_APP_FRAMERATE_CAPTURE) >= 0 && args.length == 1) {
            String app = args[0];
            MonkeyGetAppFrameRateEvent e = new MonkeyGetAppFrameRateEvent("start", app);
            mQ.addLast(e);
            return;
        }

        if (s.indexOf(EVENT_KEYWORD_END_APP_FRAMERATE_CAPTURE) >= 0 && args.length == 2) {
            String app = args[0];
            String label = args[1];
            MonkeyGetAppFrameRateEvent e = new MonkeyGetAppFrameRateEvent("end", app, label);
            mQ.addLast(e);
            return;
        }


    }

    /**
     * Extracts an event and a list of arguments from a line. If the line does
     * not match the format required, it is ignored.
     *
     * @param line A string in the form {@code cmd(arg1,arg2,arg3)}.
     */
    private void processLine(String line) {
        int index1 = line.indexOf('(');
        int index2 = line.indexOf(')');

        if (index1 < 0 || index2 < 0) {
            return;
        }

        String[] args = line.substring(index1 + 1, index2).split(",");

        for (int i = 0; i < args.length; i++) {
            args[i] = args[i].trim();
        }

        handleEvent(line, args);
    }

    /**
     * Closes the script file.
     *
     * @throws IOException If there was an error closing the file.
     */
    private void closeFile() throws IOException {
        mFileOpened = false;

        try {
            mFStream.close();
            mInputStream.close();
        } catch (NullPointerException e) {
            // File was never opened so it can't be closed.
        }
    }

    /**
     * Read next batch of events from the script file into the event queue.
     * Checks if the script is open and then reads the next MAX_ONE_TIME_READS
     * events or reads until the end of the file. If no events are read, then
     * the script is closed.
     *
     * @throws IOException If there was an error reading the file.
     */
    private void readNextBatch() throws IOException {
        int linesRead = 0;

        if (THIS_DEBUG) {
            Logger.out.println("readNextBatch(): reading next batch of events");
        }

        if (!mFileOpened) {
            resetValue();
            readHeader();
        }

        if (mReadScriptLineByLine) {
            linesRead = readOneLine();
        } else {
            linesRead = readLines();
        }

        if (linesRead == 0) {
            closeFile();
        }
    }

    /**
     * Sleep for a period of given time. Used to introduce latency between
     * events.
     *
     * @param time The amount of time to sleep in ms
     */
    private void needSleep(long time) {
        if (time < 1) {
            return;
        }
        try {
            Thread.sleep(time);
        } catch (InterruptedException e) {
        }
    }

    /**
     * Checks if the file can be opened and if the header is valid.
     *
     * @return True if the file exists and the header is valid, false otherwise.
     */
    @Override
    public boolean validate() {
        boolean validHeader;
        try {
            validHeader = readHeader();
            closeFile();
        } catch (IOException e) {
            return false;
        }

        if (mVerbose > 0) {
            Logger.out.println("Replaying " + mEventCountInScript + " events with speed " + mSpeed);
        }
        return validHeader;
    }

    @Override
    public void setVerbose(int verbose) {
        mVerbose = verbose;
    }

    /**
     * Adjust key downtime and eventtime according to both recorded values and
     * current system time.
     *
     * @param e A KeyEvent
     */
    private void adjustKeyEventTime(MonkeyKeyEvent e) {
        if (e.getEventTime() < 0) {
            return;
        }
        long thisDownTime = 0;
        long thisEventTime = 0;
        long expectedDelay = 0;

        if (mLastRecordedEventTime <= 0) {
            // first time event
            thisDownTime = SystemClock.uptimeMillis();
            thisEventTime = thisDownTime;
        } else {
            if (e.getDownTime() != mLastRecordedDownTimeKey) {
                thisDownTime = e.getDownTime();
            } else {
                thisDownTime = mLastExportDownTimeKey;
            }
            expectedDelay = (long) ((e.getEventTime() - mLastRecordedEventTime) * mSpeed);
            thisEventTime = mLastExportEventTime + expectedDelay;
            // add sleep to simulate everything in recording
            needSleep(expectedDelay - SLEEP_COMPENSATE_DIFF);
        }
        mLastRecordedDownTimeKey = e.getDownTime();
        mLastRecordedEventTime = e.getEventTime();
        e.setDownTime(thisDownTime);
        e.setEventTime(thisEventTime);
        mLastExportDownTimeKey = thisDownTime;
        mLastExportEventTime = thisEventTime;
    }

    /**
     * Adjust motion downtime and eventtime according to current system time.
     *
     * @param e A MotionEvent
     */
    private void adjustMotionEventTime(MonkeyMotionEvent e) {
        long thisEventTime = SystemClock.uptimeMillis();
        long thisDownTime = e.getDownTime();

        if (thisDownTime == mLastRecordedDownTimeMotion) {
            // this event is the same batch as previous one
            e.setDownTime(mLastExportDownTimeMotion);
        } else {
            // this event is the start of a new batch
            mLastRecordedDownTimeMotion = thisDownTime;
            // update down time to match current time
            e.setDownTime(thisEventTime);
            mLastExportDownTimeMotion = thisEventTime;
        }
        // always refresh event time
        e.setEventTime(thisEventTime);
    }

    /**
     * Gets the next event to be injected from the script. If the event queue is
     * empty, reads the next n events from the script into the queue, where n is
     * the lesser of the number of remaining events and the value specified by
     * MAX_ONE_TIME_READS. If the end of the file is reached, no events are
     * added to the queue and null is returned.
     *
     * @return The first event in the event queue or null if the end of the file
     *         is reached or if an error is encountered reading the file.
     */
    @Override
    public MonkeyEvent getNextEvent() {
        long recordedEventTime = -1;
        MonkeyEvent ev;

        if (mQ.isEmpty()) {
            try {
                readNextBatch();
            } catch (IOException e) {
                return null;
            }
        }

        try {
            ev = mQ.getFirst();
            mQ.removeFirst();
        } catch (NoSuchElementException e) {
            return null;
        }

        if (ev.getEventType() == MonkeyEvent.EVENT_TYPE_KEY) {
            adjustKeyEventTime((MonkeyKeyEvent) ev);
        } else if (ev.getEventType() == MonkeyEvent.EVENT_TYPE_TOUCH
                || ev.getEventType() == MonkeyEvent.EVENT_TYPE_TRACKBALL) {
            adjustMotionEventTime((MonkeyMotionEvent) ev);
        }
        return ev;
    }
}
