/*
 * ************************************************************************
 *
 * ADOBE SYSTEMS INCORPORATED
 * Copyright 2013 Adobe Systems Incorporated
 * All Rights Reserved.
 * NOTICE:  Adobe permits you to use, modify, and distribute this file in accordance with the 
 * terms of the Adobe license agreement accompanying it.  If you have received this file from a 
 * source other than Adobe, then your use, modification, or distribution of it requires the prior 
 * written permission of Adobe.
 *
 **************************************************************************
 */

package com.adobe.primetime.reference.ui.catalog;

import java.util.List;

import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;

import com.adobe.mediacore.PSDKErrorCode;
import com.adobe.mediacore.MediaPlayerItem;
import com.adobe.mediacore.MediaPlayerItemLoader;
import com.adobe.mediacore.MediaResource;
import com.adobe.mediacore.info.AudioTrack;
import com.adobe.mediacore.info.ClosedCaptionsTrack;
import com.adobe.mediacore.info.Profile;
import com.adobe.primetime.reference.utils.StringUtils;
import com.adobe.primetime.reference.PrimetimeReference;
import com.adobe.primetime.reference.R;
import com.adobe.primetime.reference.feeds.ReferencePlayerFeedAdapter;
import com.adobe.primetime.reference.ui.player.PlayerActivity;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

public class StreamInfoView extends Fragment {
	private final String LOG_TAG = PrimetimeReference.LOG_APP_NAME
			+ StreamInfoView.class.getSimpleName();

	private View _view;
	private Button _btnGetInfo;
	private Button _btnPlay;
	private Button _btnPlayLive;
	private EditText _editStreamUrl , _editStreamMetadataUrl, _editDRMType, _editLicenseServerUrl;
	private ViewGroup _vgStreamInfoArea;
	private ProgressBar _pbLoading;
	private Handler _handler;

	private MediaPlayerItemLoader.LoaderListener _itemLoaderListener = new MediaPlayerItemLoader.LoaderListener() {
		@Override
		public void onError(PSDKErrorCode mediaErrorCode, String description) {
			showToast("Unable to load media player item: " + description);
			enableControls();
		}

		@Override
		public void onLoadComplete(MediaPlayerItem playerItem) {
			String result;

			resetTextViewControls();

			ViewGroup infoAreaTV = _vgStreamInfoArea;
			String yes = getString(R.string.yes);
			String no = getString(R.string.no);

			// Is asset Live or VOD.
			result = playerItem.isLive() ? yes : no;
			appendText(infoAreaTV.findViewById(R.id.txtIsLive), result);

			// Is DRM protected.
			result = playerItem.isProtected() ? yes : no;
			appendText(infoAreaTV.findViewById(R.id.txtIsProtected), result);

			// Has trick play.
			result = playerItem.isTrickPlaySupported() ? yes : no;
			appendText(infoAreaTV.findViewById(R.id.txtIsTrickPlaySupported),
					result);

			// What playback speeds does it have.
			List<Float> speedList = playerItem.getAvailablePlaybackRates();
			if (speedList.size() > 0) {
				result = "";
				for (Float speed : speedList) {
					result += speed + ",";
				}
			} else {
				result = getString(R.string.none);
			}
			appendText(infoAreaTV.findViewById(R.id.txtAvailableSpeeds), result);

			// Does it have closed captioning.
			result = playerItem.hasClosedCaptions() ? yes : no;
			appendText(infoAreaTV.findViewById(R.id.txtHasCC), result);

			// What CC tracks does it have.
			List<ClosedCaptionsTrack> ccTracks = playerItem
					.getClosedCaptionsTracks();
			if (ccTracks.size() > 0) {
				result = "";
				for (ClosedCaptionsTrack ccTrack : ccTracks) {
					result += ccTrack.getName() + ",";
				}
			} else {
				result = getString(R.string.none);
			}
			appendText(infoAreaTV.findViewById(R.id.txtCCLanguages), result);

			// Has alternate audio.
			result = playerItem.hasAlternateAudio() ? yes : no;
			appendText(infoAreaTV.findViewById(R.id.txtHasAA), result);

			// What alternate audio tracks does it have.
			List<AudioTrack> audioTracks = playerItem.getAudioTracks();
			if (audioTracks.size() > 0) {
				result = "";
				for (AudioTrack audioTrack : audioTracks) {
					result += audioTrack.getName() + ",";
				}
			} else {
				result = getString(R.string.none);
			}
			appendText(infoAreaTV.findViewById(R.id.txtAATracks), result);

			// Does it have multiple profiles.
			result = playerItem.isDynamic() ? yes : no;
			appendText(infoAreaTV.findViewById(R.id.txtIsDynamic), result);

			// What the are the available profiles.
			List<Profile> profiles = playerItem.getProfiles();
			if (profiles.size() > 0) {
				result = "";
				for (Profile profile : profiles) {
					result += profile.getBitRate() + ",";
				}
			} else {
				result = getString(R.string.none);
			}
			appendText(infoAreaTV.findViewById(R.id.txtBitRates), result);

			enableControls();
		}

        @Override
        public void onBufferingBegin() {

        }

		@Override
		public void onBufferPrepared() {

		}
	};

	@Override
	public View onCreateView(LayoutInflater inflater, ViewGroup container,
			Bundle savedInstanceState) {
		PrimetimeReference.logger.i(LOG_TAG + "#onCreateView", "View created.");

		_view = inflater.inflate(R.layout.fragment_streaminfo_content,
				container, false);

		_btnGetInfo = (Button) _view.findViewById(R.id.btnGetStreamInfo);
		_btnPlay = (Button) _view.findViewById(R.id.btnPlay);
		_btnPlayLive = (Button) _view.findViewById(R.id.btnPlayLive);
		_editStreamUrl = (EditText) _view.findViewById(R.id.editStreamUrl);
        _editStreamMetadataUrl = (EditText) _view.findViewById(R.id.editStreamMetadataUrl);
		
        _editDRMType = (EditText) _view.findViewById(R.id.editDRMType);
        _editLicenseServerUrl = (EditText) _view.findViewById(R.id.editlicenseServerUrl);
		
		_vgStreamInfoArea = (LinearLayout) _view
				.findViewById(R.id.vgStreamInfoArea);
		_pbLoading = (ProgressBar) _view
				.findViewById(R.id.pbStreamInfoContentLoading);
		_pbLoading.setVisibility(View.GONE);
		_handler = new Handler();

		_btnGetInfo.setOnClickListener(new View.OnClickListener() {
			@Override
			public void onClick(View view) {
				disableControls();

				final String url = _editStreamUrl.getText().toString();
				if (StringUtils.isEmpty(url)) {
					Toast.makeText(view.getContext(),
							"Please provide an URL first.", Toast.LENGTH_SHORT)
							.show();
					enableControls();
				} else {
					loadResource(url);
				}
			}
		});

		_btnPlay.setOnClickListener(new View.OnClickListener() {
			@Override
			public void onClick(View view) {
				disableControls();
				playStream(false);
				enableControls();
			}
		});
		_btnPlayLive.setOnClickListener(new View.OnClickListener() {
			public void onClick(View view) {
				disableControls();
				playStream(true);
				enableControls();
			}
		});

		return _view;
	}

	private void playStream(final boolean isLive) {
		play(isLive);
	}

	private void loadResource(final String url) {
		_handler.post(new Runnable() {
			@Override
			public void run() {
				String extension = StringUtils.getFileExtension(url);
				MediaResource.Type type = MediaResource.Type.UNKNOWN;
				for (MediaResource.Type t : MediaResource.Type.values())
				{
					if (t.getValue().equalsIgnoreCase(extension))
					{
						type = t;
						break;
					}
				}

				MediaResource mediaResource = new MediaResource(url, type, null);
				MediaPlayerItemLoader itemLoader =
						new MediaPlayerItemLoader(getActivity().getApplicationContext(), _itemLoaderListener);
				itemLoader.load(mediaResource);
			}
		});
	}

	private void showToast(final String message) {
		_handler.post(new Runnable() {
			@Override
			public void run() {
				Toast.makeText(getActivity().getApplicationContext(), message,
						Toast.LENGTH_SHORT).show();
			}
		});
	}

	private void play(boolean live) {
		String url = _editStreamUrl.getText().toString().trim();
		if (StringUtils.isEmpty(url)) {
			Toast.makeText(getActivity().getApplicationContext(),
					"Please provide an URL first.", Toast.LENGTH_SHORT).show();
			enableControls();
		} else {
			PrimetimeReference.logger.i(LOG_TAG + "#play", "Launching content.");

			StringBuilder json = new StringBuilder();
			json.append("{ \"entries\": [ { \"content\": [ { \"url\": \"");
			json.append(url);

            String extension = StringUtils.getFileExtension(url);
            MediaResource.Type type = MediaResource.Type.UNKNOWN;
            for (MediaResource.Type t : MediaResource.Type.values())
            {
                if (t.getValue().equalsIgnoreCase(extension))
                {
                    type = t;
                    break;
                }
            }
            String contentType = "hls";
            if (type.getValue() == "mpd")
                contentType = "dash";
			
            json.append("\", \"format\": \"" + contentType + "\" } ], \"title\": \"Unknown\", ");

			//json.append("\", \"format\": \"M3U8\" } ], \"title\": \"Unknown\", ");

			String jsonLive = "\"isLive\": \"true\"";
			String jsonVOD = "\"isLive\": \"false\"";
			json.append(live ? jsonLive : jsonVOD);
			
            String drmType = _editDRMType.getText().toString().trim();
            String licenseServerUrl = _editLicenseServerUrl.getText().toString().trim();
            if (!drmType.isEmpty() && !licenseServerUrl.isEmpty())
            {
                json.append( ", \"protectionData\": { \"" + drmType + "\": \"" + licenseServerUrl + "\"  }");
            }
			
			json.append(", \"id\": \"Unknown\" } ] }");

			try {
				VideoItem item = new VideoItem(ReferencePlayerFeedAdapter
						.getInstance(new String(json)).getFirstItem());

				Intent intent = new Intent(getActivity(), PlayerActivity.class);
				intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
						| Intent.FLAG_ACTIVITY_SINGLE_TOP);
				intent.putExtra("CONTENT_INFO", item);
				startActivity(intent);
			} catch (Exception e) {
				PrimetimeReference.logger.e(LOG_TAG + "#play", "Failed to launch content.", e);
			}
		}
	}

	private void enableControls() {
		_btnGetInfo.setEnabled(true);
		_editStreamUrl.setEnabled(true);
		_btnPlay.setEnabled(true);
		_btnPlayLive.setEnabled(true);
		_vgStreamInfoArea.setVisibility(View.VISIBLE);
		_pbLoading.setVisibility(View.GONE);
	}

	private void disableControls() {
		_btnGetInfo.setEnabled(false);
		_editStreamUrl.setEnabled(false);
		_btnPlay.setEnabled(false);
		_btnPlayLive.setEnabled(false);
		_vgStreamInfoArea.setVisibility(View.GONE);
		_pbLoading.setVisibility(View.VISIBLE);
	}

	private void appendText(View view, String stringToAppend) {
		if (!(view instanceof TextView)) {
			PrimetimeReference.logger.e(LOG_TAG + "#appendText",
					"Invalid parameter received. Must be TextView.");
			return;
		}
		((TextView) view).setText(((TextView) view).getText().toString() + " "
				+ stringToAppend);
	}

	private void resetTextViewControls() {
		((TextView) _vgStreamInfoArea.findViewById(R.id.txtIsLive))
				.setText(getString(R.string.IsLive));
		((TextView) _vgStreamInfoArea.findViewById(R.id.txtIsProtected))
				.setText(getString(R.string.IsProtected));
		((TextView) _vgStreamInfoArea
				.findViewById(R.id.txtIsTrickPlaySupported))
				.setText(getString(R.string.IsTrickPlaySupported));
		((TextView) _vgStreamInfoArea.findViewById(R.id.txtAvailableSpeeds))
				.setText(getString(R.string.AvailableSpeeds));
		((TextView) _vgStreamInfoArea.findViewById(R.id.txtHasCC))
				.setText(getString(R.string.HasCC));
		((TextView) _vgStreamInfoArea.findViewById(R.id.txtCCLanguages))
				.setText(getString(R.string.CCTracks));
		((TextView) _vgStreamInfoArea.findViewById(R.id.txtHasAA))
				.setText(getString(R.string.HasAA));
		((TextView) _vgStreamInfoArea.findViewById(R.id.txtHasAA))
				.setText(getString(R.string.HasAA));
		((TextView) _vgStreamInfoArea.findViewById(R.id.txtAATracks))
				.setText(getString(R.string.AATracks));
		((TextView) _vgStreamInfoArea.findViewById(R.id.txtIsDynamic))
				.setText(getString(R.string.IsDynamic));
		((TextView) _vgStreamInfoArea.findViewById(R.id.txtBitRates))
				.setText(getString(R.string.BitRates));
	}
}
