//+------------------------------------------------------------------+
//|                                                     GlareObj.mqh |
//|                                  Copyright 2022, MetaQuotes Ltd. |
//|                             https://mql5.com/en/users/artmedia70 |
//+------------------------------------------------------------------+
#property copyright "Copyright 2022, MetaQuotes Ltd."
#property link      "https://mql5.com/en/users/artmedia70"
#property version   "1.00"
#property strict    // Necessary for mql4
//+------------------------------------------------------------------+
//| Include files                                                    |
//+------------------------------------------------------------------+
#include "WinFormBase.mqh"
//+------------------------------------------------------------------+
//| Glare object class                                               |
//+------------------------------------------------------------------+
class CGlareObj : public CWinFormBase
  {
private:
   ENUM_CANV_ELEMENT_VISUAL_EFF_STYLE m_style;        // Glare style
   color             m_color;                         // Glare color
   uchar             m_opacity;                       // Glare opacity
   uchar             m_blur;                          // Blur
//--- Draw the object glare form
   void              DrawGlareFigure(void);
   void              DrawFigureRectangle(void);
   void              DrawFigureParallelogram(void);
protected:
//--- Protected constructor with object type, chart ID and subwindow
                     CGlareObj(const ENUM_GRAPH_ELEMENT_TYPE type,
                               CGCnvElement *main_obj,CGCnvElement *base_obj,
                               const long chart_id,
                               const int subwindow,
                               const string descript,
                               const int x,
                               const int y,
                               const int w,
                               const int h);
public:
//--- Constructor indicating the main and base objects, chart ID and subwindow
                     CGlareObj(CGCnvElement *main_obj,CGCnvElement *base_obj,
                               const long chart_id,
                               const int subwindow,
                               const string descript,
                               const int x,
                               const int y,
                               const int w,
                               const int h);

//--- Supported object properties (1) integer, (2) real and (3) string ones
   virtual bool      SupportProperty(ENUM_CANV_ELEMENT_PROP_INTEGER property) { return true; }
   virtual bool      SupportProperty(ENUM_CANV_ELEMENT_PROP_DOUBLE property)  { return true; }
   virtual bool      SupportProperty(ENUM_CANV_ELEMENT_PROP_STRING property)  { return true; }
   
//--- Draw the object glare
   void              Draw(void);
//--- Redraw the object
   virtual void      Redraw(bool redraw);
//--- Set the element opacity
   virtual void      SetOpacity(const uchar value,const bool redraw=false);
//--- Initialize the properties
   void              Initialize(void);

//+------------------------------------------------------------------+
//| Methods of simplified access to object properties                |
//+------------------------------------------------------------------+
//--- (1) Set and (2) return the glare color
   void              SetColor(const color colour)                             { this.m_color=colour;     }
   color             Color(void)                                        const { return this.m_color;     }
//--- (1) Set and (2) return the opacity of the drawn glare
   void              SetOpacityDraw(const uchar opacity)                      { this.m_opacity=opacity;  }
   uchar             OpacityDraw(void)                                  const { return this.m_opacity;   }
//--- (1) Set and (2) return the glare blur
   void              SetBlur(const uchar blur)                                { this.m_blur=blur;        }
   uchar             Blur(void)                                         const { return this.m_blur;      }
//--- (1) Set and (2) return the glare visual effect
   void              SetVisualEffectStyle(const ENUM_CANV_ELEMENT_VISUAL_EFF_STYLE style)
                       { this.m_style=style;                                                             }
   ENUM_CANV_ELEMENT_VISUAL_EFF_STYLE VisualEffectStyle(void)           const { return this.m_style;     }
//--- Set the glare visual effect style as (1) rectangle and (2) parallelogram
   void              SetStyleRectangle(void)
                       { this.SetVisualEffectStyle(CANV_ELEMENT_VISUAL_EFF_STYLE_RECTANGLE);             }
   void              SetStyleParallelogramm(void)
                       { this.SetVisualEffectStyle(CANV_ELEMENT_VISUAL_EFF_STYLE_PARALLELOGRAMM);        }
  };
//+------------------------------------------------------------------+
//| Protected constructor with an object type,                       |
//| chart ID and subwindow                                           |
//+------------------------------------------------------------------+
CGlareObj::CGlareObj(const ENUM_GRAPH_ELEMENT_TYPE type,
                     CGCnvElement *main_obj,CGCnvElement *base_obj,
                     const long chart_id,
                     const int subwindow,
                     const string descript,
                     const int x,
                     const int y,
                     const int w,
                     const int h) : CWinFormBase(type,main_obj,base_obj,chart_id,subwindow,descript,x-OUTER_AREA_SIZE,y-OUTER_AREA_SIZE,w+OUTER_AREA_SIZE*2,h+OUTER_AREA_SIZE*2)
  {
//--- Set the specified graphical element type for the object and assign the library object type to the current object
   this.SetTypeElement(type);
   this.m_type=OBJECT_DE_TYPE_GGLARE;
   this.Initialize();
  }
//+------------------------------------------------------------------+
//| Constructor indicating the main and base objects,                |
//| chart ID and subwindow                                           |
//+------------------------------------------------------------------+
CGlareObj::CGlareObj(CGCnvElement *main_obj,CGCnvElement *base_obj,
                     const long chart_id,
                     const int subwindow,
                     const string descript,
                     const int x,
                     const int y,
                     const int w,
                     const int h) : CWinFormBase(GRAPH_ELEMENT_TYPE_WF_GLARE_OBJ,main_obj,base_obj,chart_id,subwindow,descript,x,y,w,h)
  {
   this.m_type=OBJECT_DE_TYPE_GGLARE; 
   this.Initialize();
  }
//+------------------------------------------------------------------+
//| Initialize the properties                                        |
//+------------------------------------------------------------------+
void CGlareObj::Initialize(void)
  {
   CGCnvElement::SetBackgroundColor(CLR_CANV_NULL,true);
   CGCnvElement::SetActive(false);
   this.SetBlur(4);
   this.SetColor(clrWhite);
   this.SetOpacity(127);
   this.m_shadow=false;
   this.SetVisibleFlag(false,false);
   this.SetVisualEffectStyle(CANV_ELEMENT_VISUAL_EFF_STYLE_RECTANGLE);
   this.SetDisplayState(CANV_ELEMENT_DISPLAY_STATE_NORMAL);
   this.SetDisplayed(false);
  }
//+------------------------------------------------------------------+
//| Set the element opacity                                          |
//+------------------------------------------------------------------+
void CGlareObj::SetOpacity(const uchar value,const bool redraw=false)
  {
   CGCnvElement::SetOpacity(0,false);
   this.SetOpacityDraw(value>(uchar)CLR_DEF_SHADOW_OPACITY ? (uchar)CLR_DEF_SHADOW_OPACITY : value);
   this.m_canvas.Update(redraw);
  }
//+------------------------------------------------------------------+
//| Draw the object glare                                            |
//+------------------------------------------------------------------+
void CGlareObj::Draw(void)
  {
   if(!this.IsVisible())
      return;
//--- Draw the glare
   this.DrawGlareFigure();
  }
//+------------------------------------------------------------------+
//| Draw the object glare form                                       |
//+------------------------------------------------------------------+
void CGlareObj::DrawGlareFigure()
  {
   switch(this.VisualEffectStyle())
     {
      case CANV_ELEMENT_VISUAL_EFF_STYLE_RECTANGLE       : this.DrawFigureRectangle();       break;
      case CANV_ELEMENT_VISUAL_EFF_STYLE_PARALLELOGRAMM  : this.DrawFigureParallelogram();   break;
      default:
        break;
     }
  }
//+------------------------------------------------------------------+
//| Draw the rectangle object glare form                             |
//+------------------------------------------------------------------+
void CGlareObj::DrawFigureRectangle(void)
  {
   CGCnvElement::DrawRectangleFill(0,0,this.Width()-1,this.Height()-1,this.m_color,this.OpacityDraw());
   CGCnvElement::Update();
  }
//+------------------------------------------------------------------+
//| Draw the shape of the object glare as a parallelogram            |
//+------------------------------------------------------------------+
void CGlareObj::DrawFigureParallelogram(void)
  {
   int array_x[]={this.Height(),this.Width()-1,this.Width()-1-this.Height(),0};
   int array_y[]={0,0,this.Height()-1,this.Height()-1};
   CGCnvElement::DrawPolygonFill(array_x,array_y,this.m_color,this.OpacityDraw());
   CGCnvElement::Update();
  }
//+------------------------------------------------------------------+
//| Redraw the object                                                |
//+------------------------------------------------------------------+
void CGlareObj::Redraw(bool redraw)
  {
   CGCnvElement::Erase(false);
   this.Draw();
   this.Crop();
   this.Update(redraw);
  }
//+------------------------------------------------------------------+
