/*
 * Copyright (C) 2010 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.videoeditor;

import java.util.ArrayList;
import java.util.Date;
import java.util.Locale;
import java.util.NoSuchElementException;
import java.util.Queue;
import java.util.concurrent.LinkedBlockingQueue;
import java.text.SimpleDateFormat;

import android.app.ActionBar;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.content.ContentValues;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.Color;
import android.graphics.Rect;
import android.graphics.Bitmap.Config;
import android.media.videoeditor.MediaItem;
import android.media.videoeditor.MediaProperties;
import android.media.videoeditor.VideoEditor;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.Looper;
import android.os.PowerManager;
import android.provider.MediaStore;
import android.text.InputType;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.Display;
import android.view.GestureDetector;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.ScaleGestureDetector;
import android.view.SurfaceHolder;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.widget.FrameLayout;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;

import com.android.videoeditor.service.ApiService;
import com.android.videoeditor.service.MovieMediaItem;
import com.android.videoeditor.service.VideoEditorProject;
import com.android.videoeditor.util.FileUtils;
import com.android.videoeditor.util.MediaItemUtils;
import com.android.videoeditor.util.StringUtils;
import com.android.videoeditor.widgets.AudioTrackLinearLayout;
import com.android.videoeditor.widgets.MediaLinearLayout;
import com.android.videoeditor.widgets.MediaLinearLayoutListener;
import com.android.videoeditor.widgets.OverlayLinearLayout;
import com.android.videoeditor.widgets.PlayheadView;
import com.android.videoeditor.widgets.PreviewSurfaceView;
import com.android.videoeditor.widgets.ScrollViewListener;
import com.android.videoeditor.widgets.TimelineHorizontalScrollView;
import com.android.videoeditor.widgets.TimelineRelativeLayout;
import com.android.videoeditor.widgets.ZoomControl;

/**
 * Main activity of the video editor. It handles video editing of
 * a project.
 */
public class VideoEditorActivity extends VideoEditorBaseActivity
        implements SurfaceHolder.Callback {
    private static final String TAG = "VideoEditorActivity";

    // State keys
    private static final String STATE_INSERT_AFTER_MEDIA_ITEM_ID = "insert_after_media_item_id";
    private static final String STATE_PLAYING = "playing";
    private static final String STATE_CAPTURE_URI = "capture_uri";
    private static final String STATE_SELECTED_POS_ID = "selected_pos_id";

    private static final String DCIM =
            Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM).toString();
    private static final String DIRECTORY = DCIM + "/Camera";

    // Dialog ids
    private static final int DIALOG_DELETE_PROJECT_ID = 1;
    private static final int DIALOG_EDIT_PROJECT_NAME_ID = 2;
    private static final int DIALOG_CHOOSE_ASPECT_RATIO_ID = 3;
    private static final int DIALOG_EXPORT_OPTIONS_ID = 4;

    public static final int DIALOG_REMOVE_MEDIA_ITEM_ID = 10;
    public static final int DIALOG_REMOVE_TRANSITION_ID = 11;
    public static final int DIALOG_CHANGE_RENDERING_MODE_ID = 12;
    public static final int DIALOG_REMOVE_OVERLAY_ID = 13;
    public static final int DIALOG_REMOVE_EFFECT_ID = 14;
    public static final int DIALOG_REMOVE_AUDIO_TRACK_ID = 15;

    // Dialog parameters
    private static final String PARAM_ASPECT_RATIOS_LIST = "aspect_ratios";
    private static final String PARAM_CURRENT_ASPECT_RATIO_INDEX = "current_aspect_ratio";

    // Request codes
    private static final int REQUEST_CODE_IMPORT_VIDEO = 1;
    private static final int REQUEST_CODE_IMPORT_IMAGE = 2;
    private static final int REQUEST_CODE_IMPORT_MUSIC = 3;
    private static final int REQUEST_CODE_CAPTURE_VIDEO = 4;
    private static final int REQUEST_CODE_CAPTURE_IMAGE = 5;

    public static final int REQUEST_CODE_EDIT_TRANSITION = 10;
    public static final int REQUEST_CODE_PICK_TRANSITION = 11;
    public static final int REQUEST_CODE_PICK_OVERLAY = 12;
    public static final int REQUEST_CODE_KEN_BURNS = 13;

    // The maximum zoom level
    private static final int MAX_ZOOM_LEVEL = 120;
    private static final int ZOOM_STEP = 2;

    // Threshold in width dip for showing title in action bar.
    private static final int SHOW_TITLE_THRESHOLD_WIDTH_DIP = 1000;

    private final TimelineRelativeLayout.LayoutCallback mLayoutCallback =
        new TimelineRelativeLayout.LayoutCallback() {

        @Override
        public void onLayoutComplete() {
            // Scroll the timeline such that the specified position
            // is in the center of the screen.
            movePlayhead(mProject.getPlayheadPos(), false);
        }
    };

    // Instance variables
    private PreviewSurfaceView mSurfaceView;
    private SurfaceHolder mSurfaceHolder;
    private boolean mHaveSurface;

    // The width and height of the preview surface. They are defined only if
    // mHaveSurface is true. If the values are still unknown (before
    // surfaceChanged() is called), mSurfaceWidth is set to -1.
    private int mSurfaceWidth, mSurfaceHeight;

    private boolean mResumed;
    private ImageView mOverlayView;
    private PreviewThread mPreviewThread;
    private View mEditorProjectView;
    private View mEditorEmptyView;
    private TimelineHorizontalScrollView mTimelineScroller;
    private TimelineRelativeLayout mTimelineLayout;
    private OverlayLinearLayout mOverlayLayout;
    private AudioTrackLinearLayout mAudioTrackLayout;
    private MediaLinearLayout mMediaLayout;
    private int mMediaLayoutSelectedPos;
    private PlayheadView mPlayheadView;
    private TextView mTimeView;
    private ImageButton mPreviewPlayButton;
    private ImageButton mPreviewRewindButton, mPreviewNextButton, mPreviewPrevButton;
    private int mActivityWidth;
    private String mInsertMediaItemAfterMediaItemId;
    private long mCurrentPlayheadPosMs;
    private ProgressDialog mExportProgressDialog;
    private ZoomControl mZoomControl;
    private PowerManager.WakeLock mCpuWakeLock;

    // Variables used in onActivityResult
    private Uri mAddMediaItemVideoUri;
    private Uri mAddMediaItemImageUri;
    private Uri mAddAudioTrackUri;
    private String mAddTransitionAfterMediaId;
    private int mAddTransitionType;
    private long mAddTransitionDurationMs;
    private String mEditTransitionAfterMediaId, mEditTransitionId;
    private int mEditTransitionType;
    private long mEditTransitionDurationMs;
    private String mAddOverlayMediaItemId;
    private Bundle mAddOverlayUserAttributes;
    private String mEditOverlayMediaItemId;
    private String mEditOverlayId;
    private Bundle mEditOverlayUserAttributes;
    private String mAddEffectMediaItemId;
    private int mAddEffectType;
    private Rect mAddKenBurnsStartRect;
    private Rect mAddKenBurnsEndRect;
    private boolean mRestartPreview;
    private Uri mCaptureMediaUri;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        final ActionBar actionBar = getActionBar();
        DisplayMetrics displayMetrics = new DisplayMetrics();
        getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
        // Only show title on large screens (width >= 1000 dip).
        int widthDip = (int) (displayMetrics.widthPixels / displayMetrics.scaledDensity);
        if (widthDip >= SHOW_TITLE_THRESHOLD_WIDTH_DIP) {
            actionBar.setDisplayOptions(actionBar.getDisplayOptions() | ActionBar.DISPLAY_SHOW_TITLE);
            actionBar.setTitle(R.string.full_app_name);
        }

        // Prepare the surface holder
        mSurfaceView = (PreviewSurfaceView) findViewById(R.id.video_view);
        mSurfaceHolder = mSurfaceView.getHolder();
        mSurfaceHolder.addCallback(this);
        mSurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);

        mOverlayView = (ImageView)findViewById(R.id.overlay_layer);

        mEditorProjectView = findViewById(R.id.editor_project_view);
        mEditorEmptyView = findViewById(R.id.empty_project_view);

        mTimelineScroller = (TimelineHorizontalScrollView)findViewById(R.id.timeline_scroller);
        mTimelineLayout = (TimelineRelativeLayout)findViewById(R.id.timeline);
        mMediaLayout = (MediaLinearLayout)findViewById(R.id.timeline_media);
        mOverlayLayout = (OverlayLinearLayout)findViewById(R.id.timeline_overlays);
        mAudioTrackLayout = (AudioTrackLinearLayout)findViewById(R.id.timeline_audio_tracks);
        mPlayheadView = (PlayheadView)findViewById(R.id.timeline_playhead);

        mPreviewPlayButton = (ImageButton)findViewById(R.id.editor_play);
        mPreviewRewindButton = (ImageButton)findViewById(R.id.editor_rewind);
        mPreviewNextButton = (ImageButton)findViewById(R.id.editor_next);
        mPreviewPrevButton = (ImageButton)findViewById(R.id.editor_prev);

        mTimeView = (TextView)findViewById(R.id.editor_time);

        actionBar.setDisplayHomeAsUpEnabled(true);

        mMediaLayout.setListener(new MediaLinearLayoutListener() {
            @Override
            public void onRequestScrollBy(int scrollBy, boolean smooth) {
                mTimelineScroller.appScrollBy(scrollBy, smooth);
            }

            @Override
            public void onRequestMovePlayhead(long scrollToTime, boolean smooth) {
                movePlayhead(scrollToTime);
            }

            @Override
            public void onAddMediaItem(String afterMediaItemId) {
                mInsertMediaItemAfterMediaItemId = afterMediaItemId;
                final Intent intent = new Intent(Intent.ACTION_PICK);
                intent.setData(MediaStore.Video.Media.EXTERNAL_CONTENT_URI);
                startActivityForResult(intent, REQUEST_CODE_IMPORT_VIDEO);
            }

            @Override
            public void onTrimMediaItemBegin(MovieMediaItem mediaItem) {
                onProjectEditStateChange(true);
            }

            @Override
            public void onTrimMediaItem(MovieMediaItem mediaItem, long timeMs) {
                updateTimelineDuration();
                if (mProject != null && isPreviewPlaying()) {
                    if (mediaItem.isVideoClip()) {
                        if (timeMs >= 0) {
                            mPreviewThread.renderMediaItemFrame(mediaItem, timeMs);
                        }
                    } else {
                        mPreviewThread.previewFrame(mProject,
                                mProject.getMediaItemBeginTime(mediaItem.getId()) + timeMs,
                                mProject.getMediaItemCount() == 0);
                    }
                }
            }

            @Override
            public void onTrimMediaItemEnd(MovieMediaItem mediaItem, long timeMs) {
                onProjectEditStateChange(false);
                // We need to repaint the timeline layout to clear the old
                // playhead position (the one drawn during trimming).
                mTimelineLayout.invalidate();
                showPreviewFrame();
            }
        });

        mAudioTrackLayout.setListener(new AudioTrackLinearLayout.AudioTracksLayoutListener() {
            @Override
            public void onAddAudioTrack() {
                final Intent intent = new Intent(Intent.ACTION_PICK);
                intent.setData(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI);
                startActivityForResult(intent, REQUEST_CODE_IMPORT_MUSIC);
            }
        });

        mTimelineScroller.addScrollListener(new ScrollViewListener() {
            // Instance variables
            private int mActiveWidth;
            private long mDurationMs;

            @Override
            public void onScrollBegin(View view, int scrollX, int scrollY, boolean appScroll) {
                if (!appScroll && mProject != null) {
                    mActiveWidth = mMediaLayout.getWidth() - mActivityWidth;
                    mDurationMs = mProject.computeDuration();
                } else {
                    mActiveWidth = 0;
                }
            }

            @Override
            public void onScrollProgress(View view, int scrollX, int scrollY, boolean appScroll) {
            }

            @Override
            public void onScrollEnd(View view, int scrollX, int scrollY, boolean appScroll) {
                // We check if the project is valid since the project may
                // close while scrolling
                if (!appScroll && mActiveWidth > 0 && mProject != null) {
                    final long timeMs = (scrollX * mDurationMs) / mActiveWidth;
                    if (setPlayhead(timeMs < 0 ? 0 : timeMs)) {
                        showPreviewFrame();
                    }
                }
            }
        });

        mTimelineScroller.setScaleListener(new ScaleGestureDetector.SimpleOnScaleGestureListener() {
            // Guard against this many scale events in the opposite direction
            private static final int SCALE_TOLERANCE = 3;

            private int mLastScaleFactorSign;
            private float mLastScaleFactor;

            @Override
            public boolean onScaleBegin(ScaleGestureDetector detector) {
                mLastScaleFactorSign = 0;
                return true;
            }

            @Override
            public boolean onScale(ScaleGestureDetector detector) {
                if (mProject == null) {
                    return false;
                }

                final float scaleFactor = detector.getScaleFactor();
                final float deltaScaleFactor = scaleFactor - mLastScaleFactor;
                if (deltaScaleFactor > 0.01f || deltaScaleFactor < -0.01f) {
                    if (scaleFactor < 1.0f) {
                        if (mLastScaleFactorSign <= 0) {
                            zoomTimeline(mProject.getZoomLevel() - ZOOM_STEP, true);
                        }

                        if (mLastScaleFactorSign > -SCALE_TOLERANCE) {
                            mLastScaleFactorSign--;
                        }
                    } else if (scaleFactor > 1.0f) {
                        if (mLastScaleFactorSign >= 0) {
                            zoomTimeline(mProject.getZoomLevel() + ZOOM_STEP, true);
                        }

                        if (mLastScaleFactorSign < SCALE_TOLERANCE) {
                            mLastScaleFactorSign++;
                        }
                    }
                }

                mLastScaleFactor = scaleFactor;
                return true;
            }

            @Override
            public void onScaleEnd(ScaleGestureDetector detector) {
            }
        });

        if (savedInstanceState != null) {
            mInsertMediaItemAfterMediaItemId = savedInstanceState.getString(
                    STATE_INSERT_AFTER_MEDIA_ITEM_ID);
            mRestartPreview = savedInstanceState.getBoolean(STATE_PLAYING);
            mCaptureMediaUri = savedInstanceState.getParcelable(STATE_CAPTURE_URI);
            mMediaLayoutSelectedPos = savedInstanceState.getInt(STATE_SELECTED_POS_ID, -1);
        } else {
            mRestartPreview = false;
            mMediaLayoutSelectedPos = -1;
        }

        // Compute the activity width
        final Display display = getWindowManager().getDefaultDisplay();
        mActivityWidth = display.getWidth();

        mSurfaceView.setGestureListener(new GestureDetector(this,
                new GestureDetector.SimpleOnGestureListener() {
                    @Override
                    public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
                            float velocityY) {
                        if (isPreviewPlaying()) {
                            return false;
                        }

                        mTimelineScroller.fling(-(int)velocityX);
                        return true;
                    }

                    @Override
                    public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX,
                            float distanceY) {
                        if (isPreviewPlaying()) {
                            return false;
                        }

                        mTimelineScroller.scrollBy((int)distanceX, 0);
                        return true;
                    }
                }));

        mZoomControl = ((ZoomControl)findViewById(R.id.editor_zoom));
        mZoomControl.setMax(MAX_ZOOM_LEVEL);
        mZoomControl.setOnZoomChangeListener(new ZoomControl.OnZoomChangeListener() {

            @Override
            public void onProgressChanged(int progress, boolean fromUser) {
                if (mProject != null) {
                    zoomTimeline(progress, false);
                }
            }
        });

        PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
        mCpuWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "Video Editor Activity CPU Wake Lock");
    }

    @Override
    public void onPause() {
        super.onPause();
        mResumed = false;

        // Stop the preview now (we will stop it in surfaceDestroyed(), but
        // that may be too late for releasing resources to other activities)
        stopPreviewThread();

        // Dismiss the export progress dialog. If the export will still be pending
        // when we return to this activity, we will display this dialog again.
        if (mExportProgressDialog != null) {
            mExportProgressDialog.dismiss();
            mExportProgressDialog = null;
        }
    }

    @Override
    public void onResume() {
        super.onResume();
        mResumed = true;

        if (mProject != null) {
            mMediaLayout.onResume();
            mAudioTrackLayout.onResume();
        }

        createPreviewThreadIfNeeded();
    }

    private void createPreviewThreadIfNeeded() {
        // We want to have the preview thread if and only if (1) we have a
        // surface, and (2) we are resumed.
        if (mHaveSurface && mResumed && mPreviewThread == null) {
            mPreviewThread = new PreviewThread(mSurfaceHolder);
            if (mSurfaceWidth != -1) {
                mPreviewThread.onSurfaceChanged(mSurfaceWidth, mSurfaceHeight);
            }
            restartPreview();
        }
    }

    @Override
    public void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);

        outState.putString(STATE_INSERT_AFTER_MEDIA_ITEM_ID, mInsertMediaItemAfterMediaItemId);
        outState.putBoolean(STATE_PLAYING, isPreviewPlaying() || mRestartPreview);
        outState.putParcelable(STATE_CAPTURE_URI, mCaptureMediaUri);
        outState.putInt(STATE_SELECTED_POS_ID, mMediaLayout.getSelectedViewPos());
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        MenuInflater inflater = getMenuInflater();
        inflater.inflate(R.menu.action_bar_menu, menu);
        return true;
    }

    @Override
    public boolean onPrepareOptionsMenu(Menu menu) {
        final boolean haveProject = (mProject != null);
        final boolean haveMediaItems = haveProject && mProject.getMediaItemCount() > 0;
        menu.findItem(R.id.menu_item_capture_video).setVisible(haveProject);
        menu.findItem(R.id.menu_item_capture_image).setVisible(haveProject);
        menu.findItem(R.id.menu_item_import_video).setVisible(haveProject);
        menu.findItem(R.id.menu_item_import_image).setVisible(haveProject);
        menu.findItem(R.id.menu_item_import_audio).setVisible(haveProject &&
                mProject.getAudioTracks().size() == 0 && haveMediaItems);
        menu.findItem(R.id.menu_item_change_aspect_ratio).setVisible(haveProject &&
                mProject.hasMultipleAspectRatios());
        menu.findItem(R.id.menu_item_edit_project_name).setVisible(haveProject);

        // Check if there is an operation pending or preview is on.
        boolean enableMenu = haveProject;
        if (enableMenu && mPreviewThread != null) {
            // Preview is in progress
            enableMenu = mPreviewThread.isStopped();
            if (enableMenu && mProjectPath != null) {
                enableMenu = !ApiService.isProjectBeingEdited(mProjectPath);
            }
        }

        menu.findItem(R.id.menu_item_export_movie).setVisible(enableMenu && haveMediaItems);
        menu.findItem(R.id.menu_item_delete_project).setVisible(enableMenu);
        menu.findItem(R.id.menu_item_play_exported_movie).setVisible(enableMenu &&
                mProject.getExportedMovieUri() != null);
        menu.findItem(R.id.menu_item_share_movie).setVisible(enableMenu &&
                mProject.getExportedMovieUri() != null);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
            case android.R.id.home: {
                // Returns to project picker if user clicks on the app icon in the action bar.
                final Intent intent = new Intent(this, ProjectsActivity.class);
                intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
                startActivity(intent);
                finish();
                return true;
            }

            case R.id.menu_item_capture_video: {
                mInsertMediaItemAfterMediaItemId = mProject.getLastMediaItemId();

                // Create parameters for Intent with filename
                final ContentValues values = new ContentValues();
                String videoFilename = DIRECTORY + '/' + getVideoOutputMediaFileTitle() + ".mp4";
                values.put(MediaStore.Video.Media.DATA, videoFilename);
                mCaptureMediaUri = getContentResolver().insert(
                        MediaStore.Video.Media.EXTERNAL_CONTENT_URI, values);
                final Intent intent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE);
                intent.putExtra(MediaStore.EXTRA_OUTPUT, mCaptureMediaUri);
                startActivityForResult(intent, REQUEST_CODE_CAPTURE_VIDEO);
                return true;
            }

            case R.id.menu_item_capture_image: {
                mInsertMediaItemAfterMediaItemId = mProject.getLastMediaItemId();

                // Create parameters for Intent with filename
                final ContentValues values = new ContentValues();
                mCaptureMediaUri = getContentResolver().insert(
                        MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
                final Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
                intent.putExtra(MediaStore.EXTRA_OUTPUT, mCaptureMediaUri);
                startActivityForResult(intent, REQUEST_CODE_CAPTURE_IMAGE);
                return true;
            }

            case R.id.menu_item_import_video: {
                mInsertMediaItemAfterMediaItemId = mProject.getLastMediaItemId();
                final Intent intent = new Intent(Intent.ACTION_PICK);
                intent.setData(MediaStore.Video.Media.EXTERNAL_CONTENT_URI);
                startActivityForResult(intent, REQUEST_CODE_IMPORT_VIDEO);
                return true;
            }

            case R.id.menu_item_import_image: {
                mInsertMediaItemAfterMediaItemId = mProject.getLastMediaItemId();
                final Intent intent = new Intent(Intent.ACTION_PICK);
                intent.setData(MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
                startActivityForResult(intent, REQUEST_CODE_IMPORT_IMAGE);
                return true;
            }

            case R.id.menu_item_import_audio: {
                final Intent intent = new Intent(Intent.ACTION_PICK);
                intent.setData(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI);
                startActivityForResult(intent, REQUEST_CODE_IMPORT_MUSIC);
                return true;
            }

            case R.id.menu_item_change_aspect_ratio: {
                final ArrayList<Integer> aspectRatiosList = mProject.getUniqueAspectRatiosList();
                final int size = aspectRatiosList.size();
                if (size > 1) {
                    final Bundle bundle = new Bundle();
                    bundle.putIntegerArrayList(PARAM_ASPECT_RATIOS_LIST, aspectRatiosList);

                    // Get the current aspect ratio index
                    final int currentAspectRatio = mProject.getAspectRatio();
                    int currentAspectRatioIndex = 0;
                    for (int i = 0; i < size; i++) {
                        final int aspectRatio = aspectRatiosList.get(i);
                        if (aspectRatio == currentAspectRatio) {
                            currentAspectRatioIndex = i;
                            break;
                        }
                    }
                    bundle.putInt(PARAM_CURRENT_ASPECT_RATIO_INDEX, currentAspectRatioIndex);
                    showDialog(DIALOG_CHOOSE_ASPECT_RATIO_ID, bundle);
                }
                return true;
            }

            case R.id.menu_item_edit_project_name: {
                showDialog(DIALOG_EDIT_PROJECT_NAME_ID);
                return true;
            }

            case R.id.menu_item_delete_project: {
                // Confirm project delete
                showDialog(DIALOG_DELETE_PROJECT_ID);
                return true;
            }

            case R.id.menu_item_export_movie: {
                // Present the user with a dialog to choose export options
                showDialog(DIALOG_EXPORT_OPTIONS_ID);
                return true;
            }

            case R.id.menu_item_play_exported_movie: {
                final Intent intent = new Intent(Intent.ACTION_VIEW);
                intent.setDataAndType(mProject.getExportedMovieUri(), "video/*");
                intent.putExtra(MediaStore.EXTRA_FINISH_ON_COMPLETION, false);
                startActivity(intent);
                return true;
            }

            case R.id.menu_item_share_movie: {
                final Intent intent = new Intent(Intent.ACTION_SEND);
                intent.putExtra(Intent.EXTRA_STREAM, mProject.getExportedMovieUri());
                intent.setType("video/*");
                startActivity(intent);
                return true;
            }

            default: {
                return false;
            }
        }
    }

    private String getVideoOutputMediaFileTitle() {
        long dateTaken = System.currentTimeMillis();
        Date date = new Date(dateTaken);
        SimpleDateFormat dateFormat = new SimpleDateFormat("'VID'_yyyyMMdd_HHmmss", Locale.US);

        return dateFormat.format(date);
    }

    @Override
    public Dialog onCreateDialog(int id, final Bundle bundle) {
        switch (id) {
            case DIALOG_CHOOSE_ASPECT_RATIO_ID: {
                final AlertDialog.Builder builder = new AlertDialog.Builder(this);
                builder.setTitle(getString(R.string.editor_change_aspect_ratio));
                final ArrayList<Integer> aspectRatios =
                    bundle.getIntegerArrayList(PARAM_ASPECT_RATIOS_LIST);
                final int count = aspectRatios.size();
                final CharSequence[] aspectRatioStrings = new CharSequence[count];
                for (int i = 0; i < count; i++) {
                    int aspectRatio = aspectRatios.get(i);
                    switch (aspectRatio) {
                        case MediaProperties.ASPECT_RATIO_11_9: {
                            aspectRatioStrings[i] = getString(R.string.aspect_ratio_11_9);
                            break;
                        }

                        case MediaProperties.ASPECT_RATIO_16_9: {
                            aspectRatioStrings[i] = getString(R.string.aspect_ratio_16_9);
                            break;
                        }

                        case MediaProperties.ASPECT_RATIO_3_2: {
                            aspectRatioStrings[i] = getString(R.string.aspect_ratio_3_2);
                            break;
                        }

                        case MediaProperties.ASPECT_RATIO_4_3: {
                            aspectRatioStrings[i] = getString(R.string.aspect_ratio_4_3);
                            break;
                        }

                        case MediaProperties.ASPECT_RATIO_5_3: {
                            aspectRatioStrings[i] = getString(R.string.aspect_ratio_5_3);
                            break;
                        }

                        default: {
                            break;
                        }
                    }
                }

                builder.setSingleChoiceItems(aspectRatioStrings,
                        bundle.getInt(PARAM_CURRENT_ASPECT_RATIO_INDEX),
                        new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        final int aspectRatio = aspectRatios.get(which);
                        ApiService.setAspectRatio(VideoEditorActivity.this, mProjectPath,
                                aspectRatio);

                        removeDialog(DIALOG_CHOOSE_ASPECT_RATIO_ID);
                    }
                });
                builder.setCancelable(true);
                builder.setOnCancelListener(new DialogInterface.OnCancelListener() {
                    @Override
                    public void onCancel(DialogInterface dialog) {
                        removeDialog(DIALOG_CHOOSE_ASPECT_RATIO_ID);
                    }
                });
                return builder.create();
            }

            case DIALOG_DELETE_PROJECT_ID: {
                return AlertDialogs.createAlert(this, getString(R.string.editor_delete_project), 0,
                                getString(R.string.editor_delete_project_question),
                                    getString(R.string.yes),
                        new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        ApiService.deleteProject(VideoEditorActivity.this, mProjectPath);
                        mProjectPath = null;
                        mProject = null;
                        enterDisabledState(R.string.editor_no_project);

                        removeDialog(DIALOG_DELETE_PROJECT_ID);
                        finish();
                    }
                }, getString(R.string.no), new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        removeDialog(DIALOG_DELETE_PROJECT_ID);
                    }
                }, new DialogInterface.OnCancelListener() {
                    @Override
                    public void onCancel(DialogInterface dialog) {
                        removeDialog(DIALOG_DELETE_PROJECT_ID);
                    }
                }, true);
            }

            case DIALOG_DELETE_BAD_PROJECT_ID: {
                return AlertDialogs.createAlert(this, getString(R.string.editor_delete_project), 0,
                                getString(R.string.editor_load_error),
                                    getString(R.string.yes),
                        new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        ApiService.deleteProject(VideoEditorActivity.this,
                                bundle.getString(PARAM_PROJECT_PATH));

                        removeDialog(DIALOG_DELETE_BAD_PROJECT_ID);
                        finish();
                    }
                }, getString(R.string.no), new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        removeDialog(DIALOG_DELETE_BAD_PROJECT_ID);
                    }
                }, new DialogInterface.OnCancelListener() {
                    @Override
                    public void onCancel(DialogInterface dialog) {
                        removeDialog(DIALOG_DELETE_BAD_PROJECT_ID);
                    }
                }, true);
            }

            case DIALOG_EDIT_PROJECT_NAME_ID: {
                if (mProject == null) {
                    return null;
                }

                return AlertDialogs.createEditDialog(this,
                    getString(R.string.editor_edit_project_name),
                    mProject.getName(),
                    getString(android.R.string.ok),
                    new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                            final TextView tv =
                                (TextView)((AlertDialog)dialog).findViewById(R.id.text_1);
                            mProject.setProjectName(tv.getText().toString());
                            getActionBar().setTitle(tv.getText());
                            removeDialog(DIALOG_EDIT_PROJECT_NAME_ID);
                        }
                    },
                    getString(android.R.string.cancel),
                    new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                            removeDialog(DIALOG_EDIT_PROJECT_NAME_ID);
                        }
                    },
                    new DialogInterface.OnCancelListener() {
                        @Override
                        public void onCancel(DialogInterface dialog) {
                            removeDialog(DIALOG_EDIT_PROJECT_NAME_ID);
                        }
                    },
                    InputType.TYPE_NULL,
                    32,
                    null);
            }

            case DIALOG_EXPORT_OPTIONS_ID: {
                if (mProject == null) {
                    return null;
                }

                return ExportOptionsDialog.create(this,
                        new ExportOptionsDialog.ExportOptionsListener() {
                    @Override
                    public void onExportOptions(int movieHeight, int movieBitrate) {
                        mPendingExportFilename = FileUtils.createMovieName(
                                MediaProperties.FILE_MP4);
                        ApiService.exportVideoEditor(VideoEditorActivity.this, mProjectPath,
                                mPendingExportFilename, movieHeight, movieBitrate);

                        removeDialog(DIALOG_EXPORT_OPTIONS_ID);

                        showExportProgress();
                    }
                }, new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        removeDialog(DIALOG_EXPORT_OPTIONS_ID);
                    }
                }, new DialogInterface.OnCancelListener() {
                    @Override
                    public void onCancel(DialogInterface dialog) {
                        removeDialog(DIALOG_EXPORT_OPTIONS_ID);
                    }
                }, mProject.getAspectRatio());
            }

            case DIALOG_REMOVE_MEDIA_ITEM_ID: {
                return mMediaLayout.onCreateDialog(id, bundle);
            }

            case DIALOG_CHANGE_RENDERING_MODE_ID: {
                return mMediaLayout.onCreateDialog(id, bundle);
            }

            case DIALOG_REMOVE_TRANSITION_ID: {
                return mMediaLayout.onCreateDialog(id, bundle);
            }

            case DIALOG_REMOVE_OVERLAY_ID: {
                return mOverlayLayout.onCreateDialog(id, bundle);
            }

            case DIALOG_REMOVE_EFFECT_ID: {
                return mMediaLayout.onCreateDialog(id, bundle);
            }

            case DIALOG_REMOVE_AUDIO_TRACK_ID: {
                return mAudioTrackLayout.onCreateDialog(id, bundle);
            }

            default: {
                return null;
            }
        }
    }


    /**
     * Called when user clicks on the button in the control panel.
     * @param target one of the "play", "rewind", "next",
     *         and "prev" buttons in the control panel
     */
    public void onClickHandler(View target) {
        final long playheadPosMs = mProject.getPlayheadPos();

        switch (target.getId()) {
            case R.id.editor_play: {
                if (mProject != null && mPreviewThread != null) {
                    if (mPreviewThread.isPlaying()) {
                        mPreviewThread.stopPreviewPlayback();
                    } else if (mProject.getMediaItemCount() > 0) {
                        mPreviewThread.startPreviewPlayback(mProject, playheadPosMs);
                    }
                }
                break;
            }

            case R.id.editor_rewind: {
                if (mProject != null && mPreviewThread != null) {
                    if (mPreviewThread.isPlaying()) {
                        mPreviewThread.stopPreviewPlayback();
                        movePlayhead(0);
                        mPreviewThread.startPreviewPlayback(mProject, 0);
                    } else {
                        movePlayhead(0);
                        showPreviewFrame();
                    }
                }
                break;
            }

            case R.id.editor_next: {
                if (mProject != null && mPreviewThread != null) {
                    final boolean restartPreview;
                    if (mPreviewThread.isPlaying()) {
                        mPreviewThread.stopPreviewPlayback();
                        restartPreview = true;
                    } else {
                        restartPreview = false;
                    }

                    final MovieMediaItem mediaItem = mProject.getNextMediaItem(playheadPosMs);
                    if (mediaItem != null) {
                        movePlayhead(mProject.getMediaItemBeginTime(mediaItem.getId()));
                        if (restartPreview) {
                            mPreviewThread.startPreviewPlayback(mProject,
                                    mProject.getPlayheadPos());
                        } else {
                            showPreviewFrame();
                        }
                    } else { // Move to the end of the timeline
                        movePlayhead(mProject.computeDuration());
                        showPreviewFrame();
                    }
                }
                break;
            }

            case R.id.editor_prev: {
                if (mProject != null && mPreviewThread != null) {
                    final boolean restartPreview;
                    if (mPreviewThread.isPlaying()) {
                        mPreviewThread.stopPreviewPlayback();
                        restartPreview = true;
                    } else {
                        restartPreview = false;
                    }

                    final MovieMediaItem mediaItem = mProject.getPreviousMediaItem(playheadPosMs);
                    if (mediaItem != null) {
                        movePlayhead(mProject.getMediaItemBeginTime(mediaItem.getId()));
                    } else { // Move to the beginning of the timeline
                        movePlayhead(0);
                    }

                    if (restartPreview) {
                        mPreviewThread.startPreviewPlayback(mProject, mProject.getPlayheadPos());
                    } else {
                        showPreviewFrame();
                    }
                }
                break;
            }

            default: {
                break;
            }
        }
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent extras) {
        super.onActivityResult(requestCode, resultCode, extras);
        if (resultCode == RESULT_CANCELED) {
            switch (requestCode) {
                case REQUEST_CODE_CAPTURE_VIDEO:
                case REQUEST_CODE_CAPTURE_IMAGE: {
                    if (mCaptureMediaUri != null) {
                        getContentResolver().delete(mCaptureMediaUri, null, null);
                        mCaptureMediaUri = null;
                    }
                    break;
                }

                default: {
                    break;
                }
            }
            return;
        }

        switch (requestCode) {
            case REQUEST_CODE_CAPTURE_VIDEO: {
                if (mProject != null) {
                    ApiService.addMediaItemVideoUri(this, mProjectPath,
                            ApiService.generateId(), mInsertMediaItemAfterMediaItemId,
                            mCaptureMediaUri, MediaItem.RENDERING_MODE_BLACK_BORDER,
                            mProject.getTheme());
                    mInsertMediaItemAfterMediaItemId = null;
                } else {
                    // Add this video after the project loads
                    mAddMediaItemVideoUri = mCaptureMediaUri;
                }
                mCaptureMediaUri = null;
                break;
            }

            case REQUEST_CODE_CAPTURE_IMAGE: {
                if (mProject != null) {
                    ApiService.addMediaItemImageUri(this, mProjectPath,
                            ApiService.generateId(), mInsertMediaItemAfterMediaItemId,
                            mCaptureMediaUri, MediaItem.RENDERING_MODE_BLACK_BORDER,
                            MediaItemUtils.getDefaultImageDuration(),
                            mProject.getTheme());
                    mInsertMediaItemAfterMediaItemId = null;
                } else {
                    // Add this image after the project loads
                    mAddMediaItemImageUri = mCaptureMediaUri;
                }
                mCaptureMediaUri = null;
                break;
            }

            case REQUEST_CODE_IMPORT_VIDEO: {
                final Uri mediaUri = extras.getData();
                if (mProject != null) {
                    if ("media".equals(mediaUri.getAuthority())) {
                        ApiService.addMediaItemVideoUri(this, mProjectPath,
                                ApiService.generateId(), mInsertMediaItemAfterMediaItemId,
                                mediaUri, MediaItem.RENDERING_MODE_BLACK_BORDER,
                                mProject.getTheme());
                    } else {
                        // Notify the user that this item needs to be downloaded.
                        Toast.makeText(this, getString(R.string.editor_video_load),
                                Toast.LENGTH_LONG).show();
                        // When the download is complete insert it into the project.
                        ApiService.loadMediaItem(this, mProjectPath, mediaUri, "video/*");
                    }
                    mInsertMediaItemAfterMediaItemId = null;
                } else {
                    // Add this video after the project loads
                    mAddMediaItemVideoUri = mediaUri;
                }
                break;
            }

            case REQUEST_CODE_IMPORT_IMAGE: {
                final Uri mediaUri = extras.getData();
                if (mProject != null) {
                    if ("media".equals(mediaUri.getAuthority())) {
                        ApiService.addMediaItemImageUri(this, mProjectPath,
                                ApiService.generateId(), mInsertMediaItemAfterMediaItemId,
                                mediaUri, MediaItem.RENDERING_MODE_BLACK_BORDER,
                                MediaItemUtils.getDefaultImageDuration(), mProject.getTheme());
                    } else {
                        // Notify the user that this item needs to be downloaded.
                        Toast.makeText(this, getString(R.string.editor_image_load),
                                Toast.LENGTH_LONG).show();
                        // When the download is complete insert it into the project.
                        ApiService.loadMediaItem(this, mProjectPath, mediaUri, "image/*");
                    }
                    mInsertMediaItemAfterMediaItemId = null;
                } else {
                    // Add this image after the project loads
                    mAddMediaItemImageUri = mediaUri;
                }
                break;
            }

            case REQUEST_CODE_IMPORT_MUSIC: {
                final Uri data = extras.getData();
                if (mProject != null) {
                    ApiService.addAudioTrack(this, mProjectPath, ApiService.generateId(), data,
                            true);
                } else {
                    mAddAudioTrackUri = data;
                }
                break;
            }

            case REQUEST_CODE_EDIT_TRANSITION: {
                final int type = extras.getIntExtra(TransitionsActivity.PARAM_TRANSITION_TYPE, -1);
                final String afterMediaId = extras.getStringExtra(
                        TransitionsActivity.PARAM_AFTER_MEDIA_ITEM_ID);
                final String transitionId = extras.getStringExtra(
                        TransitionsActivity.PARAM_TRANSITION_ID);
                final long transitionDurationMs = extras.getLongExtra(
                        TransitionsActivity.PARAM_TRANSITION_DURATION, 500);
                if (mProject != null) {
                    mMediaLayout.editTransition(afterMediaId, transitionId, type,
                            transitionDurationMs);
                } else {
                    // Add this transition after you load the project
                    mEditTransitionAfterMediaId = afterMediaId;
                    mEditTransitionId = transitionId;
                    mEditTransitionType = type;
                    mEditTransitionDurationMs = transitionDurationMs;
                }
                break;
            }

            case REQUEST_CODE_PICK_TRANSITION: {
                final int type = extras.getIntExtra(TransitionsActivity.PARAM_TRANSITION_TYPE, -1);
                final String afterMediaId = extras.getStringExtra(
                        TransitionsActivity.PARAM_AFTER_MEDIA_ITEM_ID);
                final long transitionDurationMs = extras.getLongExtra(
                        TransitionsActivity.PARAM_TRANSITION_DURATION, 500);
                if (mProject != null) {
                    mMediaLayout.addTransition(afterMediaId, type, transitionDurationMs);
                } else {
                    // Add this transition after you load the project
                    mAddTransitionAfterMediaId = afterMediaId;
                    mAddTransitionType = type;
                    mAddTransitionDurationMs = transitionDurationMs;
                }
                break;
            }

            case REQUEST_CODE_PICK_OVERLAY: {
                // If there is no overlay id, it means we are adding a new overlay.
                // Otherwise we generate a unique new id for the new overlay.
                final String mediaItemId =
                    extras.getStringExtra(OverlayTitleEditor.PARAM_MEDIA_ITEM_ID);
                final String overlayId =
                    extras.getStringExtra(OverlayTitleEditor.PARAM_OVERLAY_ID);
                final Bundle bundle =
                    extras.getBundleExtra(OverlayTitleEditor.PARAM_OVERLAY_ATTRIBUTES);
                if (mProject != null) {
                    final MovieMediaItem mediaItem = mProject.getMediaItem(mediaItemId);
                    if (mediaItem != null) {
                        if (overlayId == null) {
                            ApiService.addOverlay(this, mProject.getPath(), mediaItemId,
                                    ApiService.generateId(), bundle,
                                    mediaItem.getAppBoundaryBeginTime(),
                                    OverlayLinearLayout.DEFAULT_TITLE_DURATION);
                        } else {
                            ApiService.setOverlayUserAttributes(this, mProject.getPath(),
                                    mediaItemId, overlayId, bundle);
                        }
                        mOverlayLayout.invalidateCAB();
                    }
                } else {
                    // Add this overlay after you load the project.
                    mAddOverlayMediaItemId = mediaItemId;
                    mAddOverlayUserAttributes = bundle;
                    mEditOverlayId = overlayId;
                }
                break;
            }

            case REQUEST_CODE_KEN_BURNS: {
                final String mediaItemId = extras.getStringExtra(
                        KenBurnsActivity.PARAM_MEDIA_ITEM_ID);
                final Rect startRect = extras.getParcelableExtra(
                        KenBurnsActivity.PARAM_START_RECT);
                final Rect endRect = extras.getParcelableExtra(
                        KenBurnsActivity.PARAM_END_RECT);
                if (mProject != null) {
                    mMediaLayout.addEffect(EffectType.EFFECT_KEN_BURNS, mediaItemId,
                        startRect, endRect);
                    mMediaLayout.invalidateActionBar();
                } else {
                    // Add this effect after you load the project.
                    mAddEffectMediaItemId = mediaItemId;
                    mAddEffectType = EffectType.EFFECT_KEN_BURNS;
                    mAddKenBurnsStartRect = startRect;
                    mAddKenBurnsEndRect = endRect;
                }
                break;
            }

            default: {
                break;
            }
        }
    }

    @Override
    public void surfaceCreated(SurfaceHolder holder) {
        logd("surfaceCreated");

        mHaveSurface = true;
        mSurfaceWidth = -1;
        createPreviewThreadIfNeeded();
    }

    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
        logd("surfaceChanged: " + width + "x" + height);

        mSurfaceWidth = width;
        mSurfaceHeight = height;

        if (mPreviewThread != null) {
            mPreviewThread.onSurfaceChanged(width, height);
        }
    }

    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {
        logd("surfaceDestroyed");
        mHaveSurface = false;
        stopPreviewThread();
    }

    // Stop the preview playback if pending and quit the preview thread
    private void stopPreviewThread() {
        if (mPreviewThread != null) {
            mPreviewThread.stopPreviewPlayback();
            mPreviewThread.quit();
            mPreviewThread = null;
        }
    }

    @Override
    protected void enterTransitionalState(int statusStringId) {
        mEditorProjectView.setVisibility(View.GONE);
        mEditorEmptyView.setVisibility(View.VISIBLE);

        ((TextView)findViewById(R.id.empty_project_text)).setText(statusStringId);
        findViewById(R.id.empty_project_progress).setVisibility(View.VISIBLE);
    }

    @Override
    protected void enterDisabledState(int statusStringId) {
        mEditorProjectView.setVisibility(View.GONE);
        mEditorEmptyView.setVisibility(View.VISIBLE);

        getActionBar().setTitle(R.string.full_app_name);

        ((TextView)findViewById(R.id.empty_project_text)).setText(statusStringId);
        findViewById(R.id.empty_project_progress).setVisibility(View.GONE);
    }

    @Override
    protected void enterReadyState() {
        mEditorProjectView.setVisibility(View.VISIBLE);
        mEditorEmptyView.setVisibility(View.GONE);
    }

    @Override
    protected boolean showPreviewFrame() {
        if (mPreviewThread == null) {  // The surface is not ready yet.
            return false;
        }

        // Regenerate the preview frame
        if (mProject != null && !mPreviewThread.isPlaying() && mPendingExportFilename == null) {
            // Display the preview frame
            mPreviewThread.previewFrame(mProject, mProject.getPlayheadPos(),
                    mProject.getMediaItemCount() == 0);
        }

        return true;
    }

    @Override
    protected void updateTimelineDuration() {
        if (mProject == null) {
            return;
        }

        final long durationMs = mProject.computeDuration();

        // Resize the timeline according to the new timeline duration
        final int zoomWidth = mActivityWidth + timeToDimension(durationMs);
        final int childrenCount = mTimelineLayout.getChildCount();
        for (int i = 0; i < childrenCount; i++) {
            final View child = mTimelineLayout.getChildAt(i);
            final ViewGroup.LayoutParams lp = child.getLayoutParams();
            lp.width = zoomWidth;
            child.setLayoutParams(lp);
        }

        mTimelineLayout.requestLayout(mLayoutCallback);

        // Since the duration has changed make sure that the playhead
        // position is valid.
        if (mProject.getPlayheadPos() > durationMs) {
            movePlayhead(durationMs);
        }

        mAudioTrackLayout.updateTimelineDuration();
    }

    /**
     * Convert the time to dimension
     * At zoom level 1: one activity width = 1200 seconds
     * At zoom level 2: one activity width = 600 seconds
     * ...
     * At zoom level 100: one activity width = 12 seconds
     *
     * At zoom level 1000: one activity width = 1.2 seconds
     *
     * @param durationMs The time
     *
     * @return The dimension
     */
    private int timeToDimension(long durationMs) {
        return (int)((mProject.getZoomLevel() * mActivityWidth * durationMs) / 1200000);
    }

    /**
     * Zoom the timeline
     *
     * @param level The zoom level
     * @param updateControl true to set the control position to match the
     *      zoom level
     */
    private int zoomTimeline(int level, boolean updateControl) {
        if (level < 1 || level > MAX_ZOOM_LEVEL) {
            return mProject.getZoomLevel();
        }

        mProject.setZoomLevel(level);
        if (Log.isLoggable(TAG, Log.VERBOSE)) {
            Log.v(TAG, "zoomTimeline level: " + level + " -> " + timeToDimension(1000) + " pix/s");
        }

        updateTimelineDuration();

        if (updateControl) {
            mZoomControl.setProgress(level);
        }
        return level;
    }

    @Override
    protected void movePlayhead(long timeMs) {
        movePlayhead(timeMs, true);
    }

    private void movePlayhead(long timeMs, boolean smooth) {
        if (mProject == null) {
            return;
        }

        if (setPlayhead(timeMs)) {
            // Scroll the timeline such that the specified position
            // is in the center of the screen
            mTimelineScroller.appScrollTo(timeToDimension(timeMs), smooth);
        }
    }

    /**
     * Set the playhead at the specified time position
     *
     * @param timeMs The time position
     *
     * @return true if the playhead was set at the specified time position
     */
    private boolean setPlayhead(long timeMs) {
        // Check if the position would change
        if (mCurrentPlayheadPosMs == timeMs) {
            return false;
        }

        // Check if the time is valid. Note that invalid values are common due
        // to overscrolling the timeline
        if (timeMs < 0) {
            return false;
        } else if (timeMs > mProject.computeDuration()) {
            return false;
        }

        mCurrentPlayheadPosMs = timeMs;

        mTimeView.setText(StringUtils.getTimestampAsString(this, timeMs));
        mProject.setPlayheadPos(timeMs);
        return true;
    }

    @Override
    protected void setAspectRatio(final int aspectRatio) {
        final FrameLayout.LayoutParams lp =
            (FrameLayout.LayoutParams)mSurfaceView.getLayoutParams();

        switch (aspectRatio) {
            case MediaProperties.ASPECT_RATIO_5_3: {
                lp.width = (lp.height * 5) / 3;
                break;
            }

            case MediaProperties.ASPECT_RATIO_4_3: {
                lp.width = (lp.height * 4) / 3;
                break;
            }

            case MediaProperties.ASPECT_RATIO_3_2: {
                lp.width = (lp.height * 3) / 2;
                break;
            }

            case MediaProperties.ASPECT_RATIO_11_9: {
                lp.width = (lp.height * 11) / 9;
                break;
            }

            case MediaProperties.ASPECT_RATIO_16_9: {
                lp.width = (lp.height * 16) / 9;
                break;
            }

            default: {
                break;
            }
        }

        logd("setAspectRatio: " + aspectRatio + ", size: " + lp.width + "x" + lp.height);
        mSurfaceView.setLayoutParams(lp);
        mOverlayView.setLayoutParams(lp);
    }

    @Override
    protected MediaLinearLayout getMediaLayout() {
        return mMediaLayout;
    }

    @Override
    protected OverlayLinearLayout getOverlayLayout() {
        return mOverlayLayout;
    }

    @Override
    protected AudioTrackLinearLayout getAudioTrackLayout() {
        return mAudioTrackLayout;
    }

    @Override
    protected void onExportProgress(int progress) {
        if (mExportProgressDialog != null) {
            mExportProgressDialog.setProgress(progress);
        }
    }

    @Override
    protected void onExportComplete() {
        if (mExportProgressDialog != null) {
            mExportProgressDialog.dismiss();
            mExportProgressDialog = null;
        }
    }

    @Override
    protected void onProjectEditStateChange(boolean projectEdited) {
        logd("onProjectEditStateChange: " + projectEdited);

        mPreviewPlayButton.setAlpha(projectEdited ? 100 : 255);
        mPreviewPlayButton.setEnabled(!projectEdited);
        mPreviewRewindButton.setEnabled(!projectEdited);
        mPreviewNextButton.setEnabled(!projectEdited);
        mPreviewPrevButton.setEnabled(!projectEdited);

        mMediaLayout.invalidateActionBar();
        mOverlayLayout.invalidateCAB();
        invalidateOptionsMenu();
    }

    @Override
    protected void initializeFromProject(boolean updateUI) {
        logd("Project was clean: " + mProject.isClean());

        if (updateUI || !mProject.isClean()) {
            getActionBar().setTitle(mProject.getName());

            // Clear the media related to the previous project and
            // add the media for the current project.
            mMediaLayout.setParentTimelineScrollView(mTimelineScroller);
            mMediaLayout.setProject(mProject);
            mOverlayLayout.setProject(mProject);
            mAudioTrackLayout.setProject(mProject);
            mPlayheadView.setProject(mProject);

            // Add the media items to the media item layout
            mMediaLayout.addMediaItems(mProject.getMediaItems());
            mMediaLayout.setSelectedView(mMediaLayoutSelectedPos);

            // Add the media items to the overlay layout
            mOverlayLayout.addMediaItems(mProject.getMediaItems());

            // Add the audio tracks to the audio tracks layout
            mAudioTrackLayout.addAudioTracks(mProject.getAudioTracks());

            setAspectRatio(mProject.getAspectRatio());
        }

        updateTimelineDuration();
        zoomTimeline(mProject.getZoomLevel(), true);

        // Set the playhead position. We need to wait for the layout to
        // complete before we can scroll to the playhead position.
        final Handler handler = new Handler();
        handler.post(new Runnable() {
            private final long DELAY = 100;
            private final int ATTEMPTS = 20;
            private int mAttempts = ATTEMPTS;

            @Override
            public void run() {
                // If the surface is not yet created (showPreviewFrame()
                // returns false) wait for a while (DELAY * ATTEMPTS).
                if (showPreviewFrame() == false && mAttempts >= 0) {
                    mAttempts--;
                    if (mAttempts >= 0) {
                        handler.postDelayed(this, DELAY);
                    }
                }
            }
        });

        if (mAddMediaItemVideoUri != null) {
            ApiService.addMediaItemVideoUri(this, mProjectPath, ApiService.generateId(),
                    mInsertMediaItemAfterMediaItemId,
                    mAddMediaItemVideoUri, MediaItem.RENDERING_MODE_BLACK_BORDER,
                    mProject.getTheme());
            mAddMediaItemVideoUri = null;
            mInsertMediaItemAfterMediaItemId = null;
        }

        if (mAddMediaItemImageUri != null) {
            ApiService.addMediaItemImageUri(this, mProjectPath, ApiService.generateId(),
                    mInsertMediaItemAfterMediaItemId,
                    mAddMediaItemImageUri, MediaItem.RENDERING_MODE_BLACK_BORDER,
                    MediaItemUtils.getDefaultImageDuration(), mProject.getTheme());
            mAddMediaItemImageUri = null;
            mInsertMediaItemAfterMediaItemId = null;
        }

        if (mAddAudioTrackUri != null) {
            ApiService.addAudioTrack(this, mProject.getPath(), ApiService.generateId(),
                    mAddAudioTrackUri, true);
            mAddAudioTrackUri = null;
        }

        if (mAddTransitionAfterMediaId != null) {
            mMediaLayout.addTransition(mAddTransitionAfterMediaId, mAddTransitionType,
                    mAddTransitionDurationMs);
            mAddTransitionAfterMediaId = null;
        }

        if (mEditTransitionId != null) {
            mMediaLayout.editTransition(mEditTransitionAfterMediaId, mEditTransitionId,
                    mEditTransitionType, mEditTransitionDurationMs);
            mEditTransitionId = null;
            mEditTransitionAfterMediaId = null;
        }

        if (mAddOverlayMediaItemId != null) {
            ApiService.addOverlay(this, mProject.getPath(), mAddOverlayMediaItemId,
                    ApiService.generateId(), mAddOverlayUserAttributes, 0,
                    OverlayLinearLayout.DEFAULT_TITLE_DURATION);
            mAddOverlayMediaItemId = null;
            mAddOverlayUserAttributes = null;
        }

        if (mEditOverlayMediaItemId != null) {
            ApiService.setOverlayUserAttributes(this, mProject.getPath(), mEditOverlayMediaItemId,
                    mEditOverlayId, mEditOverlayUserAttributes);
            mEditOverlayMediaItemId = null;
            mEditOverlayId = null;
            mEditOverlayUserAttributes = null;
        }

        if (mAddEffectMediaItemId != null) {
            mMediaLayout.addEffect(mAddEffectType, mAddEffectMediaItemId,
                        mAddKenBurnsStartRect, mAddKenBurnsEndRect);
            mAddEffectMediaItemId = null;
        }

        enterReadyState();

        if (mPendingExportFilename != null) {
            if (ApiService.isVideoEditorExportPending(mProjectPath, mPendingExportFilename)) {
                // The export is still pending
                // Display the export project dialog
                showExportProgress();
            } else {
                // The export completed while the Activity was paused
                mPendingExportFilename = null;
            }
        }

        invalidateOptionsMenu();

        restartPreview();
    }

    /**
     * Restarts preview.
     */
    private void restartPreview() {
        if (mRestartPreview == false) {
            return;
        }

        if (mProject == null) {
            return;
        }

        if (mPreviewThread != null) {
            mRestartPreview = false;
            mPreviewThread.startPreviewPlayback(mProject, mProject.getPlayheadPos());
        }
    }

    /**
     * Shows progress dialog during export operation.
     */
    private void showExportProgress() {
        // Keep the CPU on throughout the export operation.
        mExportProgressDialog = new ProgressDialog(this) {
            @Override
            public void onStart() {
                super.onStart();
                mCpuWakeLock.acquire();
            }
            @Override
            public void onStop() {
                super.onStop();
                mCpuWakeLock.release();
            }
        };
        mExportProgressDialog.setTitle(getString(R.string.export_dialog_export));
        mExportProgressDialog.setMessage(null);
        mExportProgressDialog.setIndeterminate(false);
        // Allow cancellation with BACK button.
        mExportProgressDialog.setCancelable(true);
        mExportProgressDialog.setOnCancelListener(new DialogInterface.OnCancelListener() {
            @Override
            public void onCancel(DialogInterface dialog) {
                cancelExport();
            }
        });
        mExportProgressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
        mExportProgressDialog.setMax(100);
        mExportProgressDialog.setCanceledOnTouchOutside(false);
        mExportProgressDialog.setButton(getString(android.R.string.cancel),
                new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                            cancelExport();
                        }
                }
        );
        mExportProgressDialog.setCanceledOnTouchOutside(false);
        mExportProgressDialog.show();
        mExportProgressDialog.setProgressNumberFormat("");
    }

    private void cancelExport() {
        ApiService.cancelExportVideoEditor(VideoEditorActivity.this, mProjectPath,
                mPendingExportFilename);
        mPendingExportFilename = null;
        mExportProgressDialog = null;
    }

    private boolean isPreviewPlaying() {
        if (mPreviewThread == null)
            return false;

        return mPreviewThread.isPlaying();
    }

    /**
     * The preview thread
     */
    private class PreviewThread extends Thread {
        // Preview states
        private final int PREVIEW_STATE_STOPPED = 0;
        private final int PREVIEW_STATE_STARTING = 1;
        private final int PREVIEW_STATE_STARTED = 2;
        private final int PREVIEW_STATE_STOPPING = 3;

        private final int OVERLAY_DATA_COUNT = 16;

        private final Handler mMainHandler;
        private final Queue<Runnable> mQueue;
        private final SurfaceHolder mSurfaceHolder;
        private final Queue<VideoEditor.OverlayData> mOverlayDataQueue;
        private Handler mThreadHandler;
        private int mPreviewState;
        private Bitmap mOverlayBitmap;

        private final Runnable mProcessQueueRunnable = new Runnable() {
            @Override
            public void run() {
                // Process whatever accumulated in the queue
                Runnable runnable;
                while ((runnable = mQueue.poll()) != null) {
                    runnable.run();
                }
            }
        };

        /**
         * Constructor
         *
         * @param surfaceHolder The surface holder
         */
        public PreviewThread(SurfaceHolder surfaceHolder) {
            mMainHandler = new Handler(Looper.getMainLooper());
            mQueue = new LinkedBlockingQueue<Runnable>();
            mSurfaceHolder = surfaceHolder;
            mPreviewState = PREVIEW_STATE_STOPPED;

            mOverlayDataQueue = new LinkedBlockingQueue<VideoEditor.OverlayData>();
            for (int i = 0; i < OVERLAY_DATA_COUNT; i++) {
                mOverlayDataQueue.add(new VideoEditor.OverlayData());
            }

            start();
        }

        /**
         * Preview the specified frame
         *
         * @param project The video editor project
         * @param timeMs The frame time
         * @param clear true to clear the output
         */
        public void previewFrame(final VideoEditorProject project, final long timeMs,
                final boolean clear) {
            if (mPreviewState == PREVIEW_STATE_STARTING || mPreviewState == PREVIEW_STATE_STARTED) {
                stopPreviewPlayback();
            }

            logd("Preview frame at: " + timeMs + " " + clear);

            // We only need to see the last frame
            mQueue.clear();

            mQueue.add(new Runnable() {
                @Override
                public void run() {
                    if (clear) {
                        try {
                        project.clearSurface(mSurfaceHolder);
                        } catch (Exception ex) {
                            Log.w(TAG, "Surface cannot be cleared");
                        }

                        mMainHandler.post(new Runnable() {
                            @Override
                            public void run() {
                                if (mOverlayBitmap != null) {
                                    mOverlayBitmap.eraseColor(Color.TRANSPARENT);
                                    mOverlayView.invalidate();
                                }
                            }
                        });
                    } else {
                        final VideoEditor.OverlayData overlayData;
                        try {
                            overlayData = mOverlayDataQueue.remove();
                        } catch (NoSuchElementException ex) {
                            Log.e(TAG, "Out of OverlayData elements");
                            return;
                        }

                        try {
                            if (project.renderPreviewFrame(mSurfaceHolder, timeMs, overlayData)
                                    < 0) {
                                logd("Cannot render preview frame at: " + timeMs +
                                        " of " + mProject.computeDuration());

                                mOverlayDataQueue.add(overlayData);
                            } else {
                                if (overlayData.needsRendering()) {
                                    mMainHandler.post(new Runnable() {
                                        /*
                                         * {@inheritDoc}
                                         */
                                        @Override
                                        public void run() {
                                            if (mOverlayBitmap != null) {
                                                overlayData.renderOverlay(mOverlayBitmap);
                                                mOverlayView.invalidate();
                                            } else {
                                                overlayData.release();
                                            }

                                            mOverlayDataQueue.add(overlayData);
                                        }
                                    });
                                } else {
                                    mOverlayDataQueue.add(overlayData);
                                }
                            }
                        } catch (Exception ex) {
                            logd("renderPreviewFrame failed at timeMs: " + timeMs + "\n" + ex);
                            mOverlayDataQueue.add(overlayData);
                        }
                    }
                }
            });

            if (mThreadHandler != null) {
                mThreadHandler.post(mProcessQueueRunnable);
            }
        }

        /**
         * Display the frame at the specified time position
         *
         * @param mediaItem The media item
         * @param timeMs The frame time
         */
        public void renderMediaItemFrame(final MovieMediaItem mediaItem, final long timeMs) {
            if (mPreviewState == PREVIEW_STATE_STARTING || mPreviewState == PREVIEW_STATE_STARTED) {
                stopPreviewPlayback();
            }

            if (Log.isLoggable(TAG, Log.VERBOSE)) {
                Log.v(TAG, "Render media item frame at: " + timeMs);
            }

            // We only need to see the last frame
            mQueue.clear();

            mQueue.add(new Runnable() {
                @Override
                public void run() {
                    try {
                        if (mProject.renderMediaItemFrame(mSurfaceHolder, mediaItem.getId(),
                                timeMs) < 0) {
                            logd("Cannot render media item frame at: " + timeMs +
                                    " of " + mediaItem.getDuration());
                            }
                    } catch (Exception ex) {
                        logd("Cannot render preview frame at: " + timeMs + "\n" + ex);
                    }
                }
            });

            if (mThreadHandler != null) {
                mThreadHandler.post(mProcessQueueRunnable);
            }
        }

        /**
         * Starts the preview playback.
         *
         * @param project The video editor project
         * @param fromMs Start playing from the specified position
         */
        private void startPreviewPlayback(final VideoEditorProject project, final long fromMs) {
            if (mPreviewState != PREVIEW_STATE_STOPPED) {
                logd("Preview did not start: " + mPreviewState);
                return;
            }

            previewStarted(project);
            logd("Start preview at: " + fromMs);

            // Clear any pending preview frames
            mQueue.clear();
            mQueue.add(new Runnable() {
                @Override
                public void run() {
                    try {
                        project.startPreview(mSurfaceHolder, fromMs, -1, false, 3,
                                new VideoEditor.PreviewProgressListener() {
                            @Override
                            public void onStart(VideoEditor videoEditor) {
                            }

                            @Override
                            public void onProgress(VideoEditor videoEditor, final long timeMs,
                                    final VideoEditor.OverlayData overlayData) {
                                mMainHandler.post(new Runnable() {
                                    @Override
                                    public void run() {
                                        if (overlayData != null && overlayData.needsRendering()) {
                                            if (mOverlayBitmap != null) {
                                                overlayData.renderOverlay(mOverlayBitmap);
                                                mOverlayView.invalidate();
                                            } else {
                                                overlayData.release();
                                            }
                                        }

                                        if (mPreviewState == PREVIEW_STATE_STARTED ||
                                                mPreviewState == PREVIEW_STATE_STOPPING) {
                                            movePlayhead(timeMs);
                                        }
                                    }
                                });
                            }

                            @Override
                            public void onStop(VideoEditor videoEditor) {
                                mMainHandler.post(new Runnable() {
                                    @Override
                                    public void run() {
                                        if (mPreviewState == PREVIEW_STATE_STARTED ||
                                                mPreviewState == PREVIEW_STATE_STOPPING) {
                                            previewStopped(false);
                                        }
                                    }
                                });
                            }

                            public void onError(VideoEditor videoEditor, int error) {
                                Log.w(TAG, "PreviewProgressListener onError:" + error);

                                // Notify the user that some error happened.
                                mMainHandler.post(new Runnable() {
                                    @Override
                                    public void run() {
                                        String msg = getString(R.string.editor_preview_error);
                                        Toast.makeText(VideoEditorActivity.this, msg,
                                                Toast.LENGTH_LONG).show();
                                    }
                                });

                                onStop(videoEditor);
                            }
                        });

                        mMainHandler.post(new Runnable() {
                            @Override
                            public void run() {
                                mPreviewState = PREVIEW_STATE_STARTED;
                            }
                        });
                    } catch (Exception ex) {
                        // This exception may occur when trying to play frames
                        // at the end of the timeline
                        // (e.g. when fromMs == clip duration)
                        Log.w(TAG, "Cannot start preview at: " + fromMs + "\n" + ex);

                        mMainHandler.post(new Runnable() {
                            @Override
                            public void run() {
                                mPreviewState = PREVIEW_STATE_STARTED;
                                previewStopped(true);
                            }
                        });
                    }
                }
            });

            if (mThreadHandler != null) {
                mThreadHandler.post(mProcessQueueRunnable);
            }
        }

        /**
         * The preview started.
         * This method is always invoked from the UI thread.
         *
         * @param project The project
         */
        private void previewStarted(VideoEditorProject project) {
            // Change the button image back to a pause icon
            mPreviewPlayButton.setImageResource(R.drawable.btn_playback_ic_pause);

            mTimelineScroller.enableUserScrolling(false);
            mMediaLayout.setPlaybackInProgress(true);
            mOverlayLayout.setPlaybackInProgress(true);
            mAudioTrackLayout.setPlaybackInProgress(true);

            mPreviewState = PREVIEW_STATE_STARTING;

            // Keep the screen on during the preview.
            VideoEditorActivity.this.getWindow().addFlags(
                    WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
        }

        /**
         * Stops the preview.
         */
        private void stopPreviewPlayback() {
            switch (mPreviewState) {
                case PREVIEW_STATE_STOPPED: {
                    logd("stopPreviewPlayback: State was PREVIEW_STATE_STOPPED");
                    return;
                }

                case PREVIEW_STATE_STOPPING: {
                    logd("stopPreviewPlayback: State was PREVIEW_STATE_STOPPING");
                    return;
                }

                case PREVIEW_STATE_STARTING: {
                    logd("stopPreviewPlayback: State was PREVIEW_STATE_STARTING " +
                            "now PREVIEW_STATE_STOPPING");
                    mPreviewState = PREVIEW_STATE_STOPPING;

                    // We need to wait until the preview starts
                    mMainHandler.postDelayed(new Runnable() {
                        @Override
                        public void run() {
                            if (mPreviewState == PREVIEW_STATE_STARTED) {
                                logd("stopPreviewPlayback: Now PREVIEW_STATE_STARTED");
                                previewStopped(false);
                            } else if (mPreviewState == PREVIEW_STATE_STOPPING) {
                                // Keep waiting
                                mMainHandler.postDelayed(this, 100);
                                logd("stopPreviewPlayback: Waiting for PREVIEW_STATE_STARTED");
                            } else {
                                logd("stopPreviewPlayback: PREVIEW_STATE_STOPPED while waiting");
                            }
                        }
                    }, 50);
                    break;
                }

                case PREVIEW_STATE_STARTED: {
                    logd("stopPreviewPlayback: State was PREVIEW_STATE_STARTED");

                    // We need to stop
                    previewStopped(false);
                    return;
                }

                default: {
                    throw new IllegalArgumentException("stopPreviewPlayback state: " +
                            mPreviewState);
                }
            }
        }

        /**
         * The surface size has changed
         *
         * @param width The new surface width
         * @param height The new surface height
         */
        private void onSurfaceChanged(int width, int height) {
            if (mOverlayBitmap != null) {
                if (mOverlayBitmap.getWidth() == width && mOverlayBitmap.getHeight() == height) {
                    // The size has not changed
                    return;
                }

                mOverlayView.setImageBitmap(null);
                mOverlayBitmap.recycle();
                mOverlayBitmap = null;
            }

            // Create the overlay bitmap
            logd("Overlay size: " + width + " x " + height);

            mOverlayBitmap = Bitmap.createBitmap(width, height, Config.ARGB_8888);
            mOverlayView.setImageBitmap(mOverlayBitmap);
        }

        /**
         * Preview stopped. This method is always invoked from the UI thread.
         *
         * @param error true if the preview stopped due to an error
         */
        private void previewStopped(boolean error) {
            if (mProject == null) {
                Log.w(TAG, "previewStopped: project was deleted.");
                return;
            }

            if (mPreviewState != PREVIEW_STATE_STARTED) {
                throw new IllegalStateException("previewStopped in state: " + mPreviewState);
            }

            // Change the button image back to a play icon
            mPreviewPlayButton.setImageResource(R.drawable.btn_playback_ic_play);

            if (error == false) {
                // Set the playhead position at the position where the playback stopped
                final long stopTimeMs = mProject.stopPreview();
                movePlayhead(stopTimeMs);
                logd("PREVIEW_STATE_STOPPED: " + stopTimeMs);
            } else {
                logd("PREVIEW_STATE_STOPPED due to error");
            }

            mPreviewState = PREVIEW_STATE_STOPPED;

            // The playback has stopped
            mTimelineScroller.enableUserScrolling(true);
            mMediaLayout.setPlaybackInProgress(false);
            mAudioTrackLayout.setPlaybackInProgress(false);
            mOverlayLayout.setPlaybackInProgress(false);

            // Do not keep the screen on if there is no preview in progress.
            VideoEditorActivity.this.getWindow().clearFlags(
                    WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
        }

        /**
         * @return true if preview playback is in progress
         */
        private boolean isPlaying() {
            return mPreviewState == PREVIEW_STATE_STARTING ||
                    mPreviewState == PREVIEW_STATE_STARTED;
        }

        /**
         * @return true if the preview is stopped
         */
        private boolean isStopped() {
            return mPreviewState == PREVIEW_STATE_STOPPED;
        }

        @Override
        public void run() {
            setPriority(MAX_PRIORITY);
            Looper.prepare();
            mThreadHandler = new Handler();

            // Ensure that the queued items are processed
            mThreadHandler.post(mProcessQueueRunnable);

            // Run the loop
            Looper.loop();
        }

        /**
         * Quits the thread
         */
        public void quit() {
            // Release the overlay bitmap
            if (mOverlayBitmap != null) {
                mOverlayView.setImageBitmap(null);
                mOverlayBitmap.recycle();
                mOverlayBitmap = null;
            }

            if (mThreadHandler != null) {
                mThreadHandler.getLooper().quit();
                try {
                    // Wait for the thread to quit. An ANR waiting to happen.
                    mThreadHandler.getLooper().getThread().join();
                } catch (InterruptedException ex) {
                }
            }

            mQueue.clear();
        }
    }

    private static void logd(String message) {
        if (Log.isLoggable(TAG, Log.DEBUG)) {
            Log.d(TAG, message);
        }
    }
}
