//
// "00-Tick.mq4" -- draw tick
//
//    Ver. 1.00  2008/10/1(Wed)
// 
#property  copyright "00"
#property  link      "http://www.mql4.com/"

//---- indicator settings
#property  indicator_separate_window

#property  indicator_buffers  3

#property  indicator_color1  DimGray
#property  indicator_color2  DodgerBlue
#property  indicator_color3  Crimson

#property  indicator_width1  1
#property  indicator_width2  1
#property  indicator_width3  1

//---- indicator parameters
extern string symbol           = "";
extern int    nTick            = 100;
extern int    nGridMinutes     = 5;
extern int    nGridBox         = 50;
extern bool   bUpDownColorize  = true;
extern color  colGrid          = 0x140804;

//---- indicator buffers
double BufferTick[];
double BufferUp[];
double BufferDown[];

//---- vars
string sIndicatorName  = "00-Tick";
datetime g_serial;
double g_Tick[];
datetime g_Time[];
string g_sIndicatorName;
int g_volume;
string g_symbol;

//----------------------------------------------------------------------
int init()
{
    int i;
    
    g_serial = TimeLocal();
    
    SetIndexStyle(0, DRAW_LINE);
    SetIndexStyle(1, DRAW_LINE);
    SetIndexStyle(2, DRAW_LINE);
    
    SetIndexBuffer(0, BufferTick);
    SetIndexBuffer(1, BufferUp);
    SetIndexBuffer(2, BufferDown);
    
    ArrayResize(g_Tick, nTick);
    ArrayResize(g_Time, nTick);
    
    Print("Bars= ", Bars);

    return(0);
}

//----------------------------------------------------------------------
int deinit()
{
    objInit(false);
    
    return(0);
}

//----------------------------------------------------------------------
void reset()
{
    bool bOk = true;
    datetime t = TimeLocal();
    string sym = Symbol();
    
    if (symbol != "") {
	sym = symbol;
    }
    
    for (int i = 0; i < nTick; i++) {
	int shift = iBarShift(sym, 1, Time[0] - i * 60);
	double v = iClose(sym, 1, shift);
	if (v <= 0) {
	    bOk = false;
	    break;
	}
	g_Tick[i] = v;
	g_Time[i] = t - i * 60;
    }
    
    if (bOk) {
	g_symbol = sym;
	g_volume = 0;
	
	IndicatorShortName(g_sIndicatorName + " (" + g_symbol + ")");
    }
}

//----------------------------------------------------------------------
string getBoxName(int i)
{
    return(g_sIndicatorName + " " + g_serial + " " + i);
}

//----------------------------------------------------------------------
void objInit(bool bInit)
{
    for (int i = 0; i < nGridBox; i++) {
	string s = getBoxName(i);
	if (bInit) {
	    int window = WindowOnDropped();
	    ObjectCreate(s, OBJ_RECTANGLE, window, 0, 0);
	    ObjectSet(s, OBJPROP_STYLE, STYLE_SOLID);
	} else {
	    ObjectDelete(s);
	}
    }
}

//----------------------------------------------------------------------
int start()
{
    int i;
    bool bUpdate = false;
    
    objInit(true);
    
    if ((symbol == "" && Symbol() != g_symbol) ||
	(symbol != "" && symbol != g_symbol)) {
	
	reset();
	bUpdate = true;
	
	for (i = Bars; i >= 0; i--) {
	    BufferTick[i] = EMPTY_VALUE;
	    BufferUp[i]   = EMPTY_VALUE;
	    BufferDown[i] = EMPTY_VALUE;
	}
    }
    
    if (g_volume != iVolume(g_symbol, 1, 0)) {
	g_volume = iVolume(g_symbol, 1, 0);
	bUpdate = true;
	
	for (i = nTick - 1; i > 0; i--) {
	    g_Tick[i] = g_Tick[i - 1];
	    g_Time[i] = g_Time[i - 1];
	}
	
	g_Tick[0] = iClose(g_symbol, 1, 0);
	g_Time[0] = TimeLocal();
    }
    
    if (bUpdate) {
	for (i = nTick * 2; i >= nTick; i--) {
	    BufferTick[i] = EMPTY_VALUE;
	    BufferUp[i]   = EMPTY_VALUE;
	    BufferDown[i] = EMPTY_VALUE;
	}
	
	for (i = nTick - 1; i >= 0; i--) {
	    double v0 = g_Tick[i + 0];
	    double v1 = g_Tick[i + 1];
	    
	    BufferTick[i] = v0;
	    BufferUp[i]   = EMPTY_VALUE;
	    BufferDown[i] = EMPTY_VALUE;
	    
	    if (bUpDownColorize) {
		if (v0 > v1) {
		    BufferUp[i] = v0;
		} else if (v0 < v1) {
		    BufferDown[i] = v0;
		}
	    }
	}
	
	// grid
	{
	    datetime ts = MathFloor(g_Time[0] / (nGridMinutes * 60));
	    datetime te;
	    int n = 0;
	    int idx[];
	    ArrayResize(idx, nGridBox * 2);
	    if ((g_Time[0] % (2 * nGridMinutes * 60)) < nGridMinutes * 60) {
		idx[0] = 0;
		n = 1;
	    }
	    for (i = 0; i < nTick; i++) {
		te = MathFloor(g_Time[i] / (nGridMinutes * 60));
		if (te == ts) {
		    continue;
		}
		ts = te;
		idx[n] = i;
		n++;
		if (n >= nGridBox * 2) {
		    break;
		}
	    }
	    
	    for (i = 0; i < nGridBox; i++) {
		string s = getBoxName(i);
		ts = Time[idx[i * 2 + 0]];
		te = Time[idx[i * 2 + 1]];
		double lo = 0;
		double hi = 1000;
		if (i * 2 >= n) {
		    lo = 0;
		    hi = 0;
		}
		ObjectMove(s, 0, ts, lo);
		ObjectMove(s, 1, te, hi);
		ObjectSet(s, OBJPROP_COLOR, colGrid);
	    }
	    
	    WindowRedraw();
	}
    }
    
    return(0);
}
