/*
 * 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.cts.verifier.audioquality;

import com.android.cts.verifier.PassFailButtons;
import com.android.cts.verifier.R;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.graphics.Color;
import android.graphics.Typeface;
import android.media.AudioFormat;
import android.media.AudioManager;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ListView;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.AdapterView.OnItemClickListener;

import java.util.ArrayList;

/**
 * Main UI for the Android Audio Quality Verifier.
 */
public class AudioQualityVerifierActivity extends PassFailButtons.Activity implements View.OnClickListener,
        OnItemClickListener {
    public static final String TAG = "AudioQualityVerifier";

    public static final int SAMPLE_RATE = 16000;
    public static final int AUDIO_FORMAT = AudioFormat.ENCODING_PCM_16BIT;
    public static final int BYTES_PER_SAMPLE = 2;
    public static final int PLAYBACK_STREAM = AudioManager.STREAM_MUSIC;

    // Intent Extra definitions, which must match those in
    // com.google.android.voicesearch.speechservice.RecognitionController
    public static final String EXTRA_RAW_AUDIO =
            "android.speech.extras.RAW_AUDIO";

    // Communication with ExperimentService
    public static final String ACTION_EXP_STARTED =
            "com.android.cts.verifier.audioquality.EXP_STARTED";
    public static final String ACTION_EXP_FINISHED =
            "com.android.cts.verifier.audioquality.EXP_FINISHED";
    public static final String EXTRA_ABORTED =
            "com.android.cts.verifier.audioquality.ABORTED";
    public static final String EXTRA_EXP_ID =
            "com.android.cts.verifier.audioquality.EXP_ID";
    public static final String EXTRA_RUN_ALL =
            "com.android.cts.verifier.audioquality.RUN_ALL";

    // Communication with ViewResultsActivity
    public static final String EXTRA_RESULTS =
            "com.android.cts.verifier.audioquality.RESULTS";

    private Button mCalibrateButton;
    private Button mRunAllButton;
    private Button mStopButton;
    private Button mViewResultsButton;
    private Button mClearButton;

    private ListView mList;
    private TwoColumnAdapter mAdapter;

    private ProgressBar mProgress;

    private ArrayList<Experiment> mExperiments;

    private boolean mRunningExperiment;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.aq_verifier_activity);
        setInfoResources(R.string.aq_verifier, R.string.aq_verifier_info, -1);
        setResult(RESULT_CANCELED);

        mCalibrateButton = (Button) findViewById(R.id.calibrateButton);
        mRunAllButton = (Button) findViewById(R.id.runAllButton);
        mStopButton = (Button) findViewById(R.id.stopButton);
        mViewResultsButton = (Button) findViewById(R.id.viewResultsButton);
        mClearButton = (Button) findViewById(R.id.clearButton);

        mCalibrateButton.setOnClickListener(this);
        mRunAllButton.setOnClickListener(this);
        mStopButton.setOnClickListener(this);
        mViewResultsButton.setOnClickListener(this);
        mClearButton.setOnClickListener(this);

        mStopButton.setEnabled(false);

        mProgress = (ProgressBar) findViewById(R.id.progress);

        mList = (ListView) findViewById(R.id.list);
        mAdapter = new TwoColumnAdapter(this);

        mExperiments = VerifierExperiments.getExperiments(this);

        BroadcastReceiver receiver = new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
                experimentReplied(intent);
            }
        };
        IntentFilter filter = new IntentFilter();
        filter.addAction(ACTION_EXP_STARTED);
        filter.addAction(ACTION_EXP_FINISHED);
        registerReceiver(receiver, filter);

        fillAdapter();
        mList.setAdapter(mAdapter);
        mList.setOnItemClickListener(this);
        checkNotSilent();
    }

    @Override
    public void onResume() {
        super.onResume();
        mAdapter.notifyDataSetChanged(); // Update List UI
        checkNotSilent();
    }

    private void checkNotSilent() {
        AudioManager mgr = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
        mgr.setStreamMute(PLAYBACK_STREAM, false);
        int volume = mgr.getStreamVolume(PLAYBACK_STREAM);
        int max = mgr.getStreamMaxVolume(PLAYBACK_STREAM);
        Log.i(TAG, "Volume " + volume + ", max " + max);
        if (volume <= max / 10) {
            // Volume level is silent or very quiet; increase to two-thirds
            mgr.setStreamVolume(PLAYBACK_STREAM, (max * 2) / 3, AudioManager.FLAG_SHOW_UI);
        }
    }

    // Called when an experiment has completed
    private void experimentReplied(Intent intent) {
        String action = intent.getAction();
        if (ACTION_EXP_STARTED.equals(action)) {
            mStopButton.setEnabled(true);
            mRunAllButton.setEnabled(false);
        } else if (ACTION_EXP_FINISHED.equals(action)) {
            boolean mRunAll = intent.getBooleanExtra(EXTRA_RUN_ALL, false);
            boolean aborted = intent.getBooleanExtra(EXTRA_ABORTED, true);
            int expID = intent.getIntExtra(EXTRA_EXP_ID, -1);
            if (mRunAll && !aborted) {
                while (expID < mExperiments.size() - 1) {
                    if (runExperiment(++expID, true)) {
                        // OK, experiment is running
                        mAdapter.notifyDataSetChanged();
                        return;
                    }
                    // Otherwise, loop back and try the next experiment
                }
            }
            mStopButton.setEnabled(false);
            mRunAllButton.setEnabled(true);
            mRunningExperiment = false;
            mProgress.setVisibility(ProgressBar.INVISIBLE);
        }
        mAdapter.notifyDataSetChanged();
    }

    // Implements AdapterView.OnItemClickListener
    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
        if (mRunningExperiment) return;
        runExperiment(position, false);
    }

    // Begin an experiment. Returns false if the experiment is not enabled.
    private boolean runExperiment(int which, boolean all) {
        Experiment exp = mExperiments.get(which);
        if (!exp.isEnabled()) return false;
        Intent intent = new Intent(this, ExperimentService.class);
        intent.putExtra(EXTRA_EXP_ID, which);
        intent.putExtra(EXTRA_RUN_ALL, all);
        startService(intent);
        mRunningExperiment = true;
        mAdapter.notifyDataSetChanged();
        mProgress.setVisibility(ProgressBar.VISIBLE);
        return true;
    }

    // Implements View.OnClickListener:
    public void onClick(View v) {
        if (v == mCalibrateButton) {
            Intent intent = new Intent(this, CalibrateVolumeActivity.class);
            startActivity(intent);
        } else if (v == mRunAllButton) {
            if (mRunningExperiment) return;
            int expID = -1;
            while (expID < mExperiments.size() - 1) {
                if (runExperiment(++expID, true)) break;
            }
        } else if (v == mStopButton) {
            Intent intent = new Intent(this, ExperimentService.class);
            stopService(intent);
        } else if (v == mViewResultsButton) {
            Intent intent = new Intent(this, ViewResultsActivity.class);
            intent.putExtra(EXTRA_RESULTS, genReport());
            startActivity(intent);
        } else if (v == mClearButton) {
            clear();
        }
    }

    private void fillAdapter() {
        mAdapter.clear();
        for (Experiment exp : mExperiments) {
            mAdapter.add(exp.getName());
        }
    }

    class TwoColumnAdapter extends ArrayAdapter<String> {
        TwoColumnAdapter(Context context) {
            super(context, R.layout.aq_row);
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            LayoutInflater inflater = getLayoutInflater();
            View row = inflater.inflate(R.layout.aq_row, parent, false);
            TextView nameField = (TextView) row.findViewById(R.id.testName);
            TextView scoreField = (TextView) row.findViewById(R.id.testScore);
            Experiment exp = mExperiments.get(position);
            nameField.setText(exp.getName());
            scoreField.setText(exp.getScore());
            if (exp.isRunning()) {
                Typeface tf = nameField.getTypeface();
                nameField.setTypeface(tf, 1);
            }
            if (!exp.isEnabled()) {
                nameField.setTextColor(Color.GRAY);
            }
            return row;
        }
    }

    private String genReport() {
        StringBuilder sb = new StringBuilder();
        for (Experiment exp : mExperiments) {
            exp.getReport(sb);
        }
        return sb.toString();
    }

    private void clear() {
        if (mRunningExperiment) {
            Intent intent = new Intent(this, ExperimentService.class);
            stopService(intent);
        }
        for (Experiment exp : mExperiments) {
            exp.reset();
        }
        mAdapter.notifyDataSetChanged();
    }
}
