package com.castlabs.sdk.demos;

import android.app.Activity;
import android.content.res.Configuration;
import android.os.Bundle;
import androidx.annotation.Nullable;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.ViewTreeObserver;
import android.widget.FrameLayout;
import android.widget.RelativeLayout;

import com.castlabs.android.player.AbstractPlayerListener;
import com.castlabs.android.player.PlayerController;
import com.castlabs.sdk.base.subtitles.SubtitlesView;

/**
 * This class showcases how to programmatically create a {@link PlayerController} and how to
 * attach to it a {@link android.view.Surface}.
 *
 * This {@literal Activity} also showcases how to manually create a {@link SubtitlesView} to use
 * with the SDK without using a {@link com.castlabs.android.player.PlayerView}.
 */
public class PlaybackWithSurfaceDemo extends Activity implements SurfaceHolder.Callback {

	PlayerController playerController;
	private SurfaceView surfaceView;
	private RelativeLayout mainLayout;
	private float videoAspectRatio = 0f;

	@Override
	protected void onCreate(@Nullable Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.playback_surface);
		playerController = new PlayerController(this);
		surfaceView = findViewById(R.id.surfaceView);
		mainLayout = findViewById(R.id.mainLayout);

		// Scan the views we have in the mainLayout. This method will search the
		// R.id.presto_castlabs_subtitles_view and automatically bind it to the PlayerController.
		// You can get a reference to such View with findById(R.id.presto_castlabs_subtitles_view)
		// since it is already in your View tree.
		playerController.scanComponentViews(mainLayout);

		// Note that you can also create the SubtitlesView programmatically. Instead of using
		// scanComponentViews(...) you'd do the following:
		//SubtitlesView subtitlesView = new SubtitlesView(this);
		//playerController.setComponentView(R.id.presto_castlabs_subtitles_view, subtitlesView);

		surfaceView.getHolder().addCallback(this);
		playerController.addPlayerListener(new AbstractPlayerListener() {
			@Override
			public void onVideoSizeChanged(int width, int height, float pixelWidthHeightRatio) {
				videoAspectRatio = (width * pixelWidthHeightRatio) / height;
				setSurfaceSize();
			}
		});

		try {
			final Bundle extras = getIntent().getExtras();
			playerController.open(extras);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	private void setSurfaceSize() {
		if (videoAspectRatio == 0) {
			return;
		}
		int w = mainLayout.getWidth();
		int h = mainLayout.getHeight();

		float viewAR = (float) w / h;

		if (viewAR < videoAspectRatio) {
			// view is "taller" than video, adjust height
			h = (int) (w / videoAspectRatio);
		} else if (viewAR > videoAspectRatio) {
			// view is "wider" than video, adjust width
			w = (int) (h / videoAspectRatio);
		}
		surfaceView.setLayoutParams(new FrameLayout.LayoutParams(w, h));
		surfaceView.invalidate();
	}

	@Override
	public void onConfigurationChanged(Configuration newConfig) {
		super.onConfigurationChanged(newConfig);
		final View view = findViewById(R.id.surfaceView);
		ViewTreeObserver observer = view.getViewTreeObserver();
		observer.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
			@Override
			public void onGlobalLayout() {
				setSurfaceSize();
				view.getViewTreeObserver().removeOnGlobalLayoutListener(this);
			}
		});
	}

	@Override
	protected void onStart() {
		super.onStart();
	}

	@Override
	protected void onDestroy() {
		surfaceView.getHolder().removeCallback(this);
		playerController.release();
		super.onDestroy();
	}

	// SurfaceHolder callback
	@Override
	public void surfaceCreated(SurfaceHolder holder) {
		playerController.setSurface(holder.getSurface());
		setSurfaceSize();
	}

	@Override
	public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
		((SubtitlesView) findViewById(R.id.presto_castlabs_subtitles_view)).setMeasuredVideoDimensions(width, height);
	}

	@Override
	public void surfaceDestroyed(SurfaceHolder holder) {
		playerController.setSurface(null);
	}
}
