/*
 * 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.example.nativemedia;

import android.app.Activity;
import android.graphics.SurfaceTexture;
import android.media.MediaPlayer;
import android.os.Bundle;
import android.util.Log;
import android.view.Surface;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.Spinner;
import java.io.IOException;

import android.content.Context;

import android.graphics.SurfaceTexture;

import android.media.MediaPlayer.OnPreparedListener;
import android.media.MediaPlayer;

public class NativeMedia extends Activity {
    static final String TAG = "NativeMedia";

    String mSourceString = null;
    String mSinkString = null;

    // member variables for Java media player
    MediaPlayer mMediaPlayer;
    boolean mMediaPlayerIsPrepared = false;
    SurfaceView mSurfaceView1;
    SurfaceHolder mSurfaceHolder1;

    // member variables for native media player
    boolean mIsPlayingStreaming = false;
    SurfaceView mSurfaceView2;
    SurfaceHolder mSurfaceHolder2;

    VideoSink mSelectedVideoSink;
    VideoSink mJavaMediaPlayerVideoSink;
    VideoSink mNativeMediaPlayerVideoSink;

    SurfaceHolderVideoSink mSurfaceHolder1VideoSink, mSurfaceHolder2VideoSink;
    GLViewVideoSink mGLView1VideoSink, mGLView2VideoSink;

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle icicle) {
        super.onCreate(icicle);
        setContentView(R.layout.main);

        mGLView1 = (MyGLSurfaceView) findViewById(R.id.glsurfaceview1);
        mGLView2 = (MyGLSurfaceView) findViewById(R.id.glsurfaceview2);

        //setContentView(mGLView);
        //setRequestedOrientation (ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);

        // initialize native media system
        createEngine();

        // set up the Surface 1 video sink
        mSurfaceView1 = (SurfaceView) findViewById(R.id.surfaceview1);
        mSurfaceHolder1 = mSurfaceView1.getHolder();

        mSurfaceHolder1.addCallback(new SurfaceHolder.Callback() {

            public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
                Log.v(TAG, "surfaceChanged format=" + format + ", width=" + width + ", height=" +
                        height);
            }

            public void surfaceCreated(SurfaceHolder holder) {
                Log.v(TAG, "surfaceCreated");
                setSurface(holder.getSurface());
            }

            public void surfaceDestroyed(SurfaceHolder holder) {
                Log.v(TAG, "surfaceDestroyed");
            }

        });

        // set up the Surface 2 video sink
        mSurfaceView2 = (SurfaceView) findViewById(R.id.surfaceview2);
        mSurfaceHolder2 = mSurfaceView2.getHolder();

        mSurfaceHolder2.addCallback(new SurfaceHolder.Callback() {

            public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
                Log.v(TAG, "surfaceChanged format=" + format + ", width=" + width + ", height=" +
                        height);
            }

            public void surfaceCreated(SurfaceHolder holder) {
                Log.v(TAG, "surfaceCreated");
                setSurface(holder.getSurface());
            }

            public void surfaceDestroyed(SurfaceHolder holder) {
                Log.v(TAG, "surfaceDestroyed");
            }

        });

        // create Java media player
        mMediaPlayer = new MediaPlayer();

        // set up Java media player listeners
        mMediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {

            public void onPrepared(MediaPlayer mediaPlayer) {
                int width = mediaPlayer.getVideoWidth();
                int height = mediaPlayer.getVideoHeight();
                Log.v(TAG, "onPrepared width=" + width + ", height=" + height);
                if (width != 0 && height != 0 && mJavaMediaPlayerVideoSink != null) {
                    mJavaMediaPlayerVideoSink.setFixedSize(width, height);
                }
                mMediaPlayerIsPrepared = true;
                mediaPlayer.start();
            }

        });

        mMediaPlayer.setOnVideoSizeChangedListener(new MediaPlayer.OnVideoSizeChangedListener() {

            public void onVideoSizeChanged(MediaPlayer mediaPlayer, int width, int height) {
                Log.v(TAG, "onVideoSizeChanged width=" + width + ", height=" + height);
                if (width != 0 && height != 0 && mJavaMediaPlayerVideoSink != null) {
                    mJavaMediaPlayerVideoSink.setFixedSize(width, height);
                }
            }

        });

        // initialize content source spinner
        Spinner sourceSpinner = (Spinner) findViewById(R.id.source_spinner);
        ArrayAdapter<CharSequence> sourceAdapter = ArrayAdapter.createFromResource(
                this, R.array.source_array, android.R.layout.simple_spinner_item);
        sourceAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
        sourceSpinner.setAdapter(sourceAdapter);
        sourceSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {

            public void onItemSelected(AdapterView<?> parent, View view, int pos, long id) {
                mSourceString = parent.getItemAtPosition(pos).toString();
                Log.v(TAG, "onItemSelected " + mSourceString);
            }

            public void onNothingSelected(AdapterView parent) {
                Log.v(TAG, "onNothingSelected");
                mSourceString = null;
            }

        });

        // initialize video sink spinner
        Spinner sinkSpinner = (Spinner) findViewById(R.id.sink_spinner);
        ArrayAdapter<CharSequence> sinkAdapter = ArrayAdapter.createFromResource(
                this, R.array.sink_array, android.R.layout.simple_spinner_item);
        sinkAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
        sinkSpinner.setAdapter(sinkAdapter);
        sinkSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {

            public void onItemSelected(AdapterView<?> parent, View view, int pos, long id) {
                mSinkString = parent.getItemAtPosition(pos).toString();
                Log.v(TAG, "onItemSelected " + mSinkString);
                if ("Surface 1".equals(mSinkString)) {
                    if (mSurfaceHolder1VideoSink == null) {
                        mSurfaceHolder1VideoSink = new SurfaceHolderVideoSink(mSurfaceHolder1);
                    }
                    mSelectedVideoSink = mSurfaceHolder1VideoSink;
                } else if ("Surface 2".equals(mSinkString)) {
                    if (mSurfaceHolder2VideoSink == null) {
                        mSurfaceHolder2VideoSink = new SurfaceHolderVideoSink(mSurfaceHolder2);
                    }
                    mSelectedVideoSink = mSurfaceHolder2VideoSink;
                } else if ("SurfaceTexture 1".equals(mSinkString)) {
                    if (mGLView1VideoSink == null) {
                        mGLView1VideoSink = new GLViewVideoSink(mGLView1);
                    }
                    mSelectedVideoSink = mGLView1VideoSink;
                } else if ("SurfaceTexture 2".equals(mSinkString)) {
                    if (mGLView2VideoSink == null) {
                        mGLView2VideoSink = new GLViewVideoSink(mGLView2);
                    }
                    mSelectedVideoSink = mGLView2VideoSink;
                }
            }

            public void onNothingSelected(AdapterView parent) {
                Log.v(TAG, "onNothingSelected");
                mSinkString = null;
                mSelectedVideoSink = null;
            }

        });

        // initialize button click handlers

        // Java MediaPlayer start/pause

        ((Button) findViewById(R.id.start_java)).setOnClickListener(new View.OnClickListener() {

            public void onClick(View view) {
                if (mJavaMediaPlayerVideoSink == null) {
                    if (mSelectedVideoSink == null) {
                        return;
                    }
                    mSelectedVideoSink.useAsSinkForJava(mMediaPlayer);
                    mJavaMediaPlayerVideoSink = mSelectedVideoSink;
                }
                if (!mMediaPlayerIsPrepared) {
                    if (mSourceString != null) {
                        try {
                            mMediaPlayer.setDataSource(mSourceString);
                        } catch (IOException e) {
                            Log.e(TAG, "IOException " + e);
                        }
                        mMediaPlayer.prepareAsync();
                    }
                } else if (mMediaPlayer.isPlaying()) {
                    mMediaPlayer.pause();
                } else {
                    mMediaPlayer.start();
                }
            }

        });

        // native MediaPlayer start/pause

        ((Button) findViewById(R.id.start_native)).setOnClickListener(new View.OnClickListener() {

            boolean created = false;
            public void onClick(View view) {
                if (!created) {
                    if (mNativeMediaPlayerVideoSink == null) {
                        if (mSelectedVideoSink == null) {
                            return;
                        }
                        mSelectedVideoSink.useAsSinkForNative();
                        mNativeMediaPlayerVideoSink = mSelectedVideoSink;
                    }
                    if (mSourceString != null) {
                        created = createStreamingMediaPlayer(mSourceString);
                    }
                }
                if (created) {
                    mIsPlayingStreaming = !mIsPlayingStreaming;
                    setPlayingStreamingMediaPlayer(mIsPlayingStreaming);
                }
            }

        });

        // Java MediaPlayer rewind

        ((Button) findViewById(R.id.rewind_java)).setOnClickListener(new View.OnClickListener() {

            public void onClick(View view) {
                if (mMediaPlayerIsPrepared) {
                    mMediaPlayer.seekTo(0);
                }
            }

        });

        // native MediaPlayer rewind

        ((Button) findViewById(R.id.rewind_native)).setOnClickListener(new View.OnClickListener() {

            public void onClick(View view) {
                if (mNativeMediaPlayerVideoSink != null) {
                    rewindStreamingMediaPlayer();
                }
            }

        });

    }

    /** Called when the activity is about to be paused. */
    @Override
    protected void onPause()
    {
        mIsPlayingStreaming = false;
        setPlayingStreamingMediaPlayer(false);
        mGLView1.onPause();
        mGLView2.onPause();
        super.onPause();
    }

    @Override
    protected void onResume() {
        super.onResume();
        mGLView1.onResume();
        mGLView2.onResume();
    }

    /** Called when the activity is about to be destroyed. */
    @Override
    protected void onDestroy()
    {
        shutdown();
        super.onDestroy();
    }

    private MyGLSurfaceView mGLView1, mGLView2;

    /** Native methods, implemented in jni folder */
    public static native void createEngine();
    public static native boolean createStreamingMediaPlayer(String filename);
    public static native void setPlayingStreamingMediaPlayer(boolean isPlaying);
    public static native void shutdown();
    public static native void setSurface(Surface surface);
    public static native void rewindStreamingMediaPlayer();

    /** Load jni .so on initialization */
    static {
         System.loadLibrary("native-media-jni");
    }

    // VideoSink abstracts out the difference between Surface and SurfaceTexture
    // aka SurfaceHolder and GLSurfaceView
    static abstract class VideoSink {

        abstract void setFixedSize(int width, int height);
        abstract void useAsSinkForJava(MediaPlayer mediaPlayer);
        abstract void useAsSinkForNative();

    }

    static class SurfaceHolderVideoSink extends VideoSink {

        private final SurfaceHolder mSurfaceHolder;

        SurfaceHolderVideoSink(SurfaceHolder surfaceHolder) {
            mSurfaceHolder = surfaceHolder;
        }

        void setFixedSize(int width, int height) {
            mSurfaceHolder.setFixedSize(width, height);
        }

        void useAsSinkForJava(MediaPlayer mediaPlayer) {
            mediaPlayer.setDisplay(mSurfaceHolder);
        }

        void useAsSinkForNative() {
            setSurface(mSurfaceHolder.getSurface());
        }

    }

    static class GLViewVideoSink extends VideoSink {

        private final MyGLSurfaceView mMyGLSurfaceView;

        GLViewVideoSink(MyGLSurfaceView myGLSurfaceView) {
            mMyGLSurfaceView = myGLSurfaceView;
        }

        void setFixedSize(int width, int height) {
        }

        void useAsSinkForJava(MediaPlayer mediaPlayer) {
            SurfaceTexture st = mMyGLSurfaceView.getSurfaceTexture();
            Surface s = new Surface(st);
            mediaPlayer.setSurface(s);
            s.release();
        }

        void useAsSinkForNative() {
            Surface surface = new Surface(mMyGLSurfaceView.getSurfaceTexture());
            setSurface(surface);
            surface.release();
        }

    }

}
