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

import android.app.Activity;
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.os.Bundle;
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 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;

    // 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);

        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);
    }

    @Override
    public void onResume() {
        super.onResume();
        mAdapter.notifyDataSetChanged(); // Update List 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();
    }
}
