//=============================================================================
//
//  OvenMediaEngine
//
//  Created by Keukhan
//  Copyright (c) 2025 AirenSoft. All rights reserved.
//
//==============================================================================
#pragma once

#include <string>

#include "base/common_types.h"
#include "base/ovlibrary/enable_shared_from_this.h"

namespace info
{
	class Overlay : public ov::EnableSharedFromThis<info::Overlay>
	{
	public:
		Overlay(ov::String url, ov::String left, ov::String top, ov::String width, ov::String height, int32_t opacity)
			: _url(url), _left(left), _top(top), _width(width), _height(height), _opacity(opacity)
		{
		}

		Overlay() : _url(""), _left("0"), _top("0"), _width("100"), _height("100"), _opacity(100)
		{
		}

		~Overlay() override = default;

		OV_DEFINE_CONST_GETTER(GetUrl, _url)
		OV_DEFINE_CONST_GETTER(GetLeft, _left)
		OV_DEFINE_CONST_GETTER(GetTop, _top)
		OV_DEFINE_CONST_GETTER(GetWidth, _width)
		OV_DEFINE_CONST_GETTER(GetHeight, _height)
		OV_DEFINE_CONST_GETTER(GetOpacity, _opacity)

		ov::String Signature() const
		{
			return ov::String::FormatString("%s:%s:%s:%s:%s:%d", _url.CStr(), _left.CStr(), _top.CStr(), _width.CStr(), _height.CStr(), _opacity);
		}

		ov::String GetInfoString() const
		{
			return ov::String::FormatString("Overlay(url=%s, left=%s, top=%s, width=%s, height=%s, opacity=%d)",
											_url.CStr(), _left.CStr(), _top.CStr(), _width.CStr(), _height.CStr(), _opacity);
		}

		// Overlay URL
		ov::String _url;

		// Position, Size
		ov::String _left;
		ov::String _top;
		ov::String _width;
		ov::String _height;

		// Opacity is a value between 0 and 100
		// - 0   is fully transparent 
		// - 100 is fully opaque.
		int32_t _opacity;  

	public:
		// A signature value is generated by combining the list of info::Overlay instances.
		// This is used to check whether any overlay has been modified
		static size_t GetSignature(const std::vector<std::shared_ptr<info::Overlay>> &overlays)
		{
			ov::String sum = "";
			for (const auto &overlay : overlays)
			{
				sum += overlay->Signature();
			}
			return sum.Hash();
		}
	};

	class OverlayInfo : public ov::EnableSharedFromThis<info::OverlayInfo>
	{
	public:
		OverlayInfo()			= default;
		~OverlayInfo() override = default;

		OverlayInfo(ov::String output_stream_name, ov::String variant_names,
					const std::vector<std::shared_ptr<info::Overlay>> &overlays)
			: _output_stream_name(output_stream_name), _variant_names(variant_names), _overlays(overlays)
		{
		}

		OV_DEFINE_CONST_GETTER(GetOutputStreamName, _output_stream_name)
		void SetOutputStreamName(ov::String output_stream_name)
		{
			_output_stream_name = output_stream_name;
		}

		OV_DEFINE_CONST_GETTER(GetVariantNames, _variant_names)
		void SetVariantNames(ov::String variant_names)
		{
			_variant_names = variant_names;
		}

		OV_DEFINE_CONST_GETTER(GetOverlays, _overlays)
		void SetOverlays(const std::vector<std::shared_ptr<info::Overlay>> &overlays)
		{
			_overlays = overlays;
		}
		void ClearOverlays()
		{
			_overlays.clear();
		}

		ov::String GetInfoString() const
		{
			ov::String overlays_info;
			for (const auto &overlay : _overlays)
			{
				overlays_info += overlay->GetInfoString() + "; ";
			}
			return ov::String::FormatString("OverlayInfo(outputStreamName=%s, variantNames=%s, overlays=[%s])",
											_output_stream_name.CStr(), _variant_names.CStr(), overlays_info.CStr());
		}

	private:
		ov::String _output_stream_name;
		ov::String _variant_names;
		std::vector<std::shared_ptr<info::Overlay>> _overlays;
	};

}  // namespace info