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

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.media.audiofx.Visualizer;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.util.Log;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.CompoundButton;
import android.widget.CompoundButton.OnCheckedChangeListener;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.ToggleButton;
import android.widget.SeekBar;

import java.nio.ByteOrder;
import java.nio.ByteBuffer;
import java.util.HashMap;
import java.util.Map;

public class VisualizerTest extends Activity implements OnCheckedChangeListener {

    private final static String TAG = "Visualizer Test";

    private Visualizer mVisualizer;
    ToggleButton mOnOffButton;
    ToggleButton mReleaseButton;
    boolean mEnabled;
    EditText mSessionText;
    static int sSession = 0;
    int mCaptureSize;
    ToggleButton mCallbackButton;
    boolean mCallbackOn;
    VisualizerListener mVisualizerListener;
    private static HashMap<Integer, Visualizer> sInstances = new HashMap<Integer, Visualizer>(10);
    private VisualizerTestHandler mVisualizerTestHandler = null;

    public VisualizerTest() {
        Log.d(TAG, "contructor");
    }

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

        TextView textView;

        setContentView(R.layout.visualizertest);

        mSessionText = (EditText) findViewById(R.id.sessionEdit);
        mSessionText.setOnKeyListener(mSessionKeyListener);
        mSessionText.setText(Integer.toString(sSession));

        mReleaseButton = (ToggleButton)findViewById(R.id.visuReleaseButton);
        mOnOffButton = (ToggleButton)findViewById(R.id.visualizerOnOff);
        mCallbackButton = (ToggleButton)findViewById(R.id.visuCallbackOnOff);
        mCallbackOn = false;
        mCallbackButton.setChecked(mCallbackOn);

        mVisualizerTestHandler = new VisualizerTestHandler();
        mVisualizerListener = new VisualizerListener();

        getEffect(sSession);

        if (mVisualizer != null) {
            mReleaseButton.setOnCheckedChangeListener(this);
            mOnOffButton.setOnCheckedChangeListener(this);
            mCallbackButton.setOnCheckedChangeListener(this);
        }
    }

    private static final int MSG_START_CAPTURE = 0;
    private static final int MSG_STOP_CAPTURE = 1;
    private static final int MSG_NEW_CAPTURE = 2;
    private static final int CAPTURE_PERIOD_MS = 100;

    private class VisualizerTestHandler extends Handler {
        boolean mActive = false;
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
            case MSG_START_CAPTURE:
                if (!mActive) {
                    Log.d(TAG, "Start capture");
                    mActive = true;
                    sendMessageDelayed(obtainMessage(MSG_NEW_CAPTURE, 0, 0, null), CAPTURE_PERIOD_MS);
                }
                break;
            case MSG_STOP_CAPTURE:
                if (mActive) {
                    Log.d(TAG, "Stop capture");
                    mActive = false;
                }
                break;
            case MSG_NEW_CAPTURE:
                if (mActive && mVisualizer != null) {
                    if (mCaptureSize > 0) {
                        byte[] data = new byte[mCaptureSize];
                        if (mVisualizer.getWaveForm(data) == Visualizer.SUCCESS) {
                            int len = data.length < mCaptureSize ? data.length : mCaptureSize;
                            displayVal(R.id.waveformMin, data[0]);
                            displayVal(R.id.waveformMax, data[len-1]);
                            displayVal(R.id.waveformCenter, data[len/2]);
                        };
                        if (mVisualizer.getFft(data) == Visualizer.SUCCESS) {
                            int len = data.length < mCaptureSize ? data.length : mCaptureSize;
                            displayVal(R.id.fftMin, data[0]);
                            displayVal(R.id.fftMax, data[len-1]);
                            displayVal(R.id.fftCenter, data[len/2]);
                        };
                    }
                    sendMessageDelayed(obtainMessage(MSG_NEW_CAPTURE, 0, 0, null), CAPTURE_PERIOD_MS);
                }
                break;
            }
        }
    }

    private class VisualizerListener implements Visualizer.OnDataCaptureListener {

        public VisualizerListener() {
        }
        public void onWaveFormDataCapture(Visualizer visualizer, byte[] waveform, int samplingRate) {
            if (visualizer == mVisualizer) {
                if (waveform.length > 0) {
                    Log.d(TAG, "onWaveFormDataCapture(): "+waveform[0]+" smp rate: "+samplingRate/1000);
                    displayVal(R.id.waveformMin, waveform[0]);
                    displayVal(R.id.waveformMax, waveform[waveform.length - 1]);
                    displayVal(R.id.waveformCenter, waveform[waveform.length/2]);
                }
            }
        }
        public void onFftDataCapture(Visualizer visualizer, byte[] fft, int samplingRate) {
            if (visualizer == mVisualizer) {
                if (fft.length > 0) {
                    Log.d(TAG, "onFftDataCapture(): "+fft[0]);
                    displayVal(R.id.fftMin, fft[0]);
                    displayVal(R.id.fftMax, fft[fft.length - 1]);
                    displayVal(R.id.fftCenter, fft[fft.length/2]);
                }
            }
        }
    }

    @Override
    public void onResume() {
        super.onResume();
    }

    @Override
    public void onPause() {
        super.onPause();
    }

    private View.OnKeyListener mSessionKeyListener
    = new View.OnKeyListener() {
        public boolean onKey(View v, int keyCode, KeyEvent event) {
            if (event.getAction() == KeyEvent.ACTION_DOWN) {
                switch (keyCode) {
                    case KeyEvent.KEYCODE_DPAD_CENTER:
                    case KeyEvent.KEYCODE_ENTER:
                        try {
                            sSession = Integer.parseInt(mSessionText.getText().toString());
                            getEffect(sSession);
                        } catch (NumberFormatException e) {
                            Log.d(TAG, "Invalid session #: "+mSessionText.getText().toString());
                        }

                        return true;
                }
            }
            return false;
        }
    };

    // OnCheckedChangeListener
    public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
        if (buttonView.getId() == R.id.visualizerOnOff) {
            if (mVisualizer != null) {
                mEnabled = isChecked;
                mCallbackButton.setEnabled(!mEnabled);
                if (mCallbackOn && mEnabled) {
                    mVisualizer.setDataCaptureListener(mVisualizerListener,
                            10000,
                            true,
                            true);
                }
                mVisualizer.setEnabled(mEnabled);
                if (mCallbackOn) {
                    if (!mEnabled) {
                        mVisualizer.setDataCaptureListener(null,
                                10000,
                                false,
                                false);
                    }
                } else {
                    int msg = isChecked ? MSG_START_CAPTURE : MSG_STOP_CAPTURE;
                    mVisualizerTestHandler.sendMessage(
                            mVisualizerTestHandler.obtainMessage(msg, 0, 0, null));
                }
            }
        }
        if (buttonView.getId() == R.id.visuReleaseButton) {
            if (isChecked) {
                if (mVisualizer == null) {
                    getEffect(sSession);
                }
            } else {
                if (mVisualizer != null) {
                    putEffect(sSession);
                }
            }
        }
        if (buttonView.getId() == R.id.visuCallbackOnOff) {
            mCallbackOn = isChecked;
        }
    }

    private void displayVal(int viewId, int val) {
        TextView textView = (TextView)findViewById(viewId);
        String text = Integer.toString(val);
        textView.setText(text);
    }


    private void getEffect(int session) {
        synchronized (sInstances) {
            if (sInstances.containsKey(session)) {
                mVisualizer = sInstances.get(session);
            } else {
                try{
                    mVisualizer = new Visualizer(session);
                } catch (UnsupportedOperationException e) {
                    Log.e(TAG,"Visualizer library not loaded");
                    throw (new RuntimeException("Cannot initialize effect"));
                } catch (RuntimeException e) {
                    throw e;
                }
                sInstances.put(session, mVisualizer);
            }
        }
        mReleaseButton.setEnabled(false);
        mOnOffButton.setEnabled(false);
        if (mVisualizer != null) {
            mCaptureSize = mVisualizer.getCaptureSize();

            mReleaseButton.setChecked(true);
            mReleaseButton.setEnabled(true);

            mEnabled = mVisualizer.getEnabled();
            mOnOffButton.setChecked(mEnabled);
            mOnOffButton.setEnabled(true);

            mCallbackButton.setEnabled(!mEnabled);
        }
    }

    private void putEffect(int session) {
        mOnOffButton.setChecked(false);
        mOnOffButton.setEnabled(false);
        synchronized (sInstances) {
            if (mVisualizer != null) {
                mVisualizer.release();
                Log.d(TAG,"Visualizer released");
                mVisualizer = null;
                sInstances.remove(session);
            }
        }
    }

}
