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

import com.android.cts.verifier.R;

import android.content.Intent;
import android.database.Cursor;
import android.media.tv.TvContentRating;
import android.media.tv.TvContract;
import android.media.tv.TvInputManager;
import android.media.tv.TvTrackInfo;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;

/**
 * Tests for verifying TV app behavior on multiple tracks and subtitle.
 */
public class MultipleTracksTestActivity extends TvAppVerifierActivity
        implements View.OnClickListener {
    private static final String TAG = "MultipleTracksTestActivity";

    private static final long TIMEOUT_MS = 5l * 60l * 1000l;  // 5 mins.

    private View mSelectSubtitleItem;
    private View mVerifySetCaptionEnabledItem;
    private View mVerifySelectSubtitleItem;
    private View mSelectAudioItem;
    private View mVerifySelectAudioItem;

    private Intent mTvAppIntent = null;

    @Override
    public void onClick(View v) {
        final View postTarget = getPostTarget();

        if (containsButton(mSelectSubtitleItem, v)) {
            final Runnable failCallback = new Runnable() {
                @Override
                public void run() {
                    setPassState(mVerifySetCaptionEnabledItem, false);
                    setPassState(mVerifySelectSubtitleItem, false);
                }
            };
            postTarget.postDelayed(failCallback, TIMEOUT_MS);
            MockTvInputService.expectSetCaptionEnabled(true, postTarget, new Runnable() {
                @Override
                public void run() {
                    postTarget.removeCallbacks(failCallback);
                    setPassState(mSelectSubtitleItem, true);
                    setPassState(mVerifySetCaptionEnabledItem, true);
                    Integer tag = (Integer) mSelectAudioItem.getTag();
                    if (tag == 0) {
                        mSelectAudioItem.setTag(Integer.valueOf(1));
                    } else if (tag == 1) {
                        setButtonEnabled(mSelectAudioItem, true);
                    }
                }
            });
            MockTvInputService.expectSelectTrack(TvTrackInfo.TYPE_SUBTITLE,
                    MockTvInputService.sEngSubtitleTrack.getId(), postTarget, new Runnable() {
                @Override
                public void run() {
                    postTarget.removeCallbacks(failCallback);
                    setPassState(mSelectSubtitleItem, true);
                    setPassState(mVerifySelectSubtitleItem, true);
                    Integer tag = (Integer) mSelectAudioItem.getTag();
                    if (tag == 0) {
                        mSelectAudioItem.setTag(Integer.valueOf(1));
                    } else if (tag == 1) {
                        setButtonEnabled(mSelectAudioItem, true);
                    }
                }
            });
        } else if (containsButton(mSelectAudioItem, v)) {
            final Runnable failCallback = new Runnable() {
                @Override
                public void run() {
                    setPassState(mVerifySelectAudioItem, false);
                }
            };
            postTarget.postDelayed(failCallback, TIMEOUT_MS);
            MockTvInputService.expectSelectTrack(TvTrackInfo.TYPE_AUDIO,
                    MockTvInputService.sSpaAudioTrack.getId(), postTarget, new Runnable() {
                @Override
                public void run() {
                    postTarget.removeCallbacks(failCallback);
                    setPassState(mSelectAudioItem, true);
                    setPassState(mVerifySelectAudioItem, true);
                    getPassButton().setEnabled(true);
                }
            });
        }
        if (mTvAppIntent == null) {
            String[] projection = { TvContract.Channels._ID };
            try (Cursor cursor = getContentResolver().query(TvContract.Channels.CONTENT_URI,
                    projection, null, null, null)) {
                if (cursor != null && cursor.moveToNext()) {
                    mTvAppIntent = new Intent(Intent.ACTION_VIEW,
                            TvContract.buildChannelUri(cursor.getLong(0)));
                }
            }
            if (mTvAppIntent == null) {
                Toast.makeText(this, R.string.tv_channel_not_found, Toast.LENGTH_SHORT).show();
                return;
            }
        }
        startActivity(mTvAppIntent);
    }

    @Override
    protected void createTestItems() {
        mSelectSubtitleItem = createUserItem(
                R.string.tv_multiple_tracks_test_select_subtitle,
                R.string.tv_launch_tv_app, this);
        setButtonEnabled(mSelectSubtitleItem, true);
        mVerifySetCaptionEnabledItem = createAutoItem(
                R.string.tv_multiple_tracks_test_verify_set_caption_enabled);
        mVerifySelectSubtitleItem = createAutoItem(
                R.string.tv_multiple_tracks_test_verify_select_subtitle);
        mSelectAudioItem = createUserItem(
                R.string.tv_multiple_tracks_test_select_audio,
                R.string.tv_launch_tv_app, this);
        mSelectAudioItem.setTag(Integer.valueOf(0));
        mVerifySelectAudioItem = createAutoItem(
                R.string.tv_multiple_tracks_test_verify_select_audio);
    }

    @Override
    protected void setInfoResources() {
        setInfoResources(R.string.tv_multiple_tracks_test,
                R.string.tv_multiple_tracks_test_info, -1);
    }
}
