//+------------------------------------------------------------------+
//|                                                testMouseMove.mq4 |
//|                        Copyright 2015, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "RickBery"
#property link      "https://www.mql5.com"
#property version   "1.00"
#property strict
#property indicator_chart_window

input color  colLines1 = clrBlue;
input color  colLines2 = clrRed;

string prefix = "SyncCursor_";
string nameV = prefix + "time";
string nameH = prefix + "price";

string nameGVTime = prefix + "GV_time";
string nameGVPrice = prefix + "GV_price";

/*
TODO:
- parameter LineStyle
*/

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
   ChartSetInteger(0,CHART_EVENT_MOUSE_MOVE,true);
   CreateVLine(nameV, TimeCurrent(), STYLE_SOLID, 1, colLines1);
	CreateHLine(nameH,Bid, STYLE_SOLID, 1, colLines2);
	
	EventSetMillisecondTimer(200);

   return(INIT_SUCCEEDED);
  }

void OnDeinit(const int reason)
{
	ObjectDelete(nameV);
	ObjectDelete(nameH);
}
  
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
                const int prev_calculated,
                const datetime &time[],
                const double &open[],
                const double &high[],
                const double &low[],
                const double &close[],
                const long &tick_volume[],
                const long &volume[],
                const int &spread[])
  {
//---
   
//--- return value of prev_calculated for next call
   return(rates_total);
  }
  
  //+------------------------------------------------------------------+
//| Timer function                                                   |
//+------------------------------------------------------------------+
void OnTimer()
  {
  	// in the "slave" chart, each timer events reads the global vars and updates the cursor
  	
	datetime dt   = GlobalVariableGet(nameGVTime);
	double price  = GlobalVariableGet(nameGVPrice);  
	if( dt>0 && price>0 )
	{
		UpdateBoth(dt,price);

		// compute timestamps of left and right borders of chart		         
    int idxLeft = ChartGetInteger(0,CHART_FIRST_VISIBLE_BAR,0);
    int wBars = ChartGetInteger(0,CHART_WIDTH_IN_BARS,0);

	int idxRight = MathMax(0, idxLeft-wBars);

    double dtLeft = idxLeft>=0 ? iTime(NULL,0,idxLeft) : 0;
    double dtRight = idxLeft>=0 && wBars>0 ? iTime(NULL,0,idxRight) : 0;
    
         // change color of hor. line when vertical line (time) is outside of the chart
    	if( dt<dtLeft )
    		ObjectSet(nameH, OBJPROP_COLOR, clrRed);
   		else
	    	if( dt>dtRight )
	    		ObjectSet(nameH, OBJPROP_COLOR, clrGreen);
	    	else
	    		ObjectSet(nameH, OBJPROP_COLOR, colLines2);
	}
  }
  
//+------------------------------------------------------------------+
//| ChartEvent function                                              |
//+------------------------------------------------------------------+
void OnChartEvent(const int id,
                  const long &lparam,
                  const double &dparam,
                  const string &sparam)
  {
 	// in the "master" chart, a mouse move updates the cursor AND sets the global vars   
	if (id==CHARTEVENT_MOUSE_MOVE) 
	{
      //--- Prepare variables 
      int      x     =(int)lparam; 
      int      y     =(int)dparam; 
      datetime dt    =0; 
      double   price =0; 
      int      window=0; 
      
      //--- Convert the X and Y coordinates in terms of date/time 
	if(ChartXYToTimePrice(0,x,y,window,dt,price)) 
	{ 
          GlobalVariableSet(nameGVTime,dt);
          GlobalVariableSet(nameGVPrice,price);

		// update cursor            
         UpdateBoth(dt,price); 
    		
         ChartRedraw(0); 
        } 
	}
}


void UpdateBoth( datetime dt, double price )
{
	ObjectMove(nameV,0,dt,0); 
	ObjectMove(nameH,0,0,price); 
}

void CreateVLine(string name, datetime t1, int style, int width, color col )
{  
	ObjectDelete(name);
	ObjectCreate(name, OBJ_VLINE, 0, t1, 0);
	ObjectSet(name, OBJPROP_COLOR	, col);
	ObjectSet(name, OBJPROP_STYLE	, style);
	ObjectSet(name, OBJPROP_WIDTH	, width);
	ObjectSetString(0,name, OBJPROP_TOOLTIP, "\n");	// disable tooltip
}

void CreateHLine(string name, double p1, int style, int width, color col )
{  
	ObjectDelete(name);
	ObjectCreate(name, OBJ_HLINE, 0, TimeCurrent(), p1);
	ObjectSet(name, OBJPROP_COLOR	, col);
	ObjectSet(name, OBJPROP_STYLE	, style);
	ObjectSet(name, OBJPROP_WIDTH	, width);
	ObjectSetString(0,name, OBJPROP_TOOLTIP, "\n");	// disable tooltip
}

//+------------------------------------------------------------------+
