//
// "00-TimeSync_v101.mq4" -- Synchronize time positions of charts in separate windows
//
//    Ver. 1.00  2009/02/15(Sun)  initial version
//    Ver. 1.01  2009/02/17(Tue)  bugfixed: focus is gone after scrolling
//
//
#property  copyright "00"
#property  link      "http://www.mql4.com/"

#include <winuser32.mqh>

#import "user32.dll"
int GetForegroundWindow();
int PeekMessageA(int msg[64], int, int, int, int);
int GetMessageA(int msg[64], int, int, int);
int TranslateMessage(int msg[64]);
int DispatchMessageA(int msg[64]);
#import

//---- defines
#define VK_BACK        0x08
#define VK_RETURN      0x0D
#define VK_DELETE      0x2E
#define VK_OEM_1       0xBA
#define VK_OEM_PERIOD  0xBE
#define N_MAX_SYMBOL   10

//---- indicator settings
#property  indicator_chart_window

#property  indicator_buffers  0

//---- indicator parameters
extern string sSymbol1   = "";  // sync windows set this symbol
extern string sSymbol2   = "";  // 
extern string sSymbol3   = "";  // 
extern string sSymbol4   = "";  // 
extern string sSymbol5   = "";  // 
extern string sSymbol6   = "";  // 
extern string sSymbol7   = "";  // 
extern string sSymbol8   = "";  // 
extern string sSymbol9   = "";  // 

//---- indicator buffers

//---- vars
string sIndicatorName;
string sIndSelf  = "00-TimeSync_v100";
string s_sSymbol[N_MAX_SYMBOL];
int    s_iSymbol[N_MAX_SYMBOL];
int    s_nSymbol;

//----------------------------------------------------------------------
string TimeFrameToStr(int timeFrame)
{
    switch (timeFrame) {
    case 1:     return("M1");
    case 5:     return("M5");
    case 15:    return("M15");
    case 30:    return("M30");
    case 60:    return("H1");
    case 240:   return("H4");
    case 1440:  return("D1");
    case 10080: return("W1");
    case 43200: return("MN");
    }
    
    return("??");
}

//----------------------------------------------------------------------
void init()
{
    string tf = TimeFrameToStr(Period());
    sIndicatorName = sIndSelf + "(" + tf + ")";
    
    IndicatorShortName(sIndicatorName);
    
    s_sSymbol[0] = Symbol();  // own symbol
    s_sSymbol[1] = sSymbol1;
    s_sSymbol[2] = sSymbol2;
    s_sSymbol[3] = sSymbol3;
    s_sSymbol[4] = sSymbol4;
    s_sSymbol[5] = sSymbol5;
    s_sSymbol[6] = sSymbol6;
    s_sSymbol[7] = sSymbol7;
    s_sSymbol[8] = sSymbol8;
    s_sSymbol[9] = sSymbol9;
    
    s_nSymbol = 0;
    for (int i = 0; i < N_MAX_SYMBOL; i++) {
	if (s_sSymbol[i] != "") {
	    s_iSymbol[s_nSymbol] = i;
	    s_nSymbol++;
	}
    }
}

//----------------------------------------------------------------------
void start()
{
    int activeWindow = GetActiveWindow();
    int foregroundWindow = GetForegroundWindow();
    
    if (activeWindow != foregroundWindow) {
	// not active
	return;
    }
    
    if (GetFocus() != WindowHandle(Symbol(), Period())) {
	// focus on other windows
	return;
    }
    
    static int periodTab[] = {
	PERIOD_M1,
	PERIOD_M5,
	PERIOD_M15,
	PERIOD_M30,
	PERIOD_H1,
	PERIOD_H4,
	PERIOD_D1,
	PERIOD_W1,
	PERIOD_MN1
    };
    
    int ibar = WindowFirstVisibleBar();
    datetime t = Time[ibar];
    string sTime = TimeYear(t) + "." + TimeMonth(t) + "." + TimeDay(t) + " " + TimeHour(t) + ":" + TimeMinute(t);
    
    int nPeriod = ArraySize(periodTab);
    
    for (int s = 0; s < s_nSymbol; s++) {
	string sSymbol = s_sSymbol[s_iSymbol[s]];
	for (int i = 0; i < nPeriod; i++) {
	    int period = periodTab[i];
	    if (sSymbol == Symbol() && period == Period()) {
		continue;
	    }
	    int hWnd = WindowHandle(sSymbol, period);
	    if (hWnd == NULL) {
		continue;
	    }
	    
	    SetFocus(hWnd);
	    
	    keybd_event(VK_RETURN, 0, 0, 0);
	    keybd_event(VK_RETURN, 0, KEYEVENTF_KEYUP, 0);
	    for (int k = 0; k < 20; k++) {  // StringLen("2009.02.15 13:10")
		keybd_event(VK_BACK, 0, 0, 0);
		keybd_event(VK_BACK, 0, KEYEVENTF_KEYUP, 0);
		keybd_event(VK_DELETE, 0, 0, 0);
		keybd_event(VK_DELETE, 0, KEYEVENTF_KEYUP, 0);
	    }
	    int nChar = StringLen(sTime);
	    for (k = 0; k < nChar; k++) {
		int key = StringGetChar(sTime, k);
		if (key == ':') {
		    key = VK_OEM_1;  // keyboard depend
		} else if (key == '.') {
		    key = VK_OEM_PERIOD;
		}
		keybd_event(key, 0, 0, 0);
		keybd_event(key, 0, KEYEVENTF_KEYUP, 0);
	    }
	    keybd_event(VK_RETURN, 0, 0, 0);
	    keybd_event(VK_RETURN, 0, KEYEVENTF_KEYUP, 0);
	    
	    // process remaining messages
	    int msg[64];
	    while (PeekMessageA(msg, NULL, 0, 0, 0) != 0) {
		if (!GetMessageA(msg, NULL, 0, 0)) {
		    break;
		}
		TranslateMessage(msg);
		DispatchMessageA(msg);
	    }
	}
    }
    
    // get focus
    hWnd = WindowHandle(Symbol(), Period());
    if (hWnd) {
	SetFocus(hWnd);
    }
}
