#define			OBJNAME_LABEL		"Alerter Label"
#define			OBJDESC_PATTERN		"Alert_"
// import of shell32.dll so we can use windows API function ShellExecuteA to launch our external mailer EXE
#import "shell32.dll"
int ShellExecuteW(int hwnd,string Operation,string File,string Parameters,string Directory,int ShowCmd);
#import
// constants for function _lopen
#define OF_READ               0
#define OF_WRITE              1
#define OF_READWRITE          2
#define OF_SHARE_COMPAT       3
#define OF_SHARE_DENY_NONE    4
#define OF_SHARE_DENY_READ    5
#define OF_SHARE_DENY_WRITE   6
#define OF_SHARE_EXCLUSIVE    7
 
// import kernel32.dll so we can use Windows API FileWrite function to write to a text file ( or INI file in this case ). 
#import "kernel32.dll"
   int _lopen  (string path, int of);
   int _lcreat (string path, int attrib);
   int _llseek (int handle, int offset, int origin);
   int _lread  (int handle, string buffer, int bytes);
   int _lwrite (int handle, string buffer, int bytes);
   int _lclose (int handle);
   bool CopyFileW(string lpExistingFileName,string lpNewFileName,bool bFailIfExists);
#import


#property indicator_chart_window

//extern bool		EmailAlert	= false;
extern bool		PopupAlert	= true;
extern bool    Screenshot  = true;
extern int     imgresolution_x   = 1280;
extern int     imgresolution_y   = 720;
string  pathtoMT4     = TerminalInfoString(TERMINAL_DATA_PATH)+"\\";
extern string  SmtpServer    = "";
extern string  fromName      = "";
extern string  fromAddress   = "";
extern string  ToAddress     = "";
extern string  CcAddress     = "";
extern string  BccAddress    = "";
extern string  SmtpUsername  = "";
extern string  SmtpPassword  = "";
extern string  SmtpIPPort    = "";
extern string  SSL           = "0";


//Function to write string to a file using Windows API instead of MQL
//This overcomes limitation of directories and only writing to CSV or BIN files 
// i.e. we can wrtie to an INI or TXT file , and will allow writing to the 
//Alertmailer.ini file with the email subject & body so we get custom text
//in our emails - along with the screenshot.

void WriteFile (string path, string buffer) 
  {
  
   int handle = FileOpen(path, FILE_READ | FILE_WRITE | FILE_TXT, 0);
  
   FileWriteString(handle, buffer);
   FileClose(handle);
  }

int init() {
	createIndicatorLabel(OBJNAME_LABEL);
	return(0);
}

int deinit() {
	ObjectDelete(OBJNAME_LABEL);
	return(0);
}

int start() {

	// Iterate over objects on this chart
	for (int i=ObjectsTotal()-1;i>=0;i--) {
		string	sObjName 	= ObjectName(i);
		double	dObjPrice;
		int		iObjAlert;
		int		iProximity;
		string	sMessage;
		
		// Can we get a price for this object?  If not, continue iteration
		dObjPrice = getObjectPrice(sObjName);
		if (dObjPrice == -1) continue;
		
		// Is there an alert on this object?  If not, continue iteration
		iObjAlert = getObjectAlert(sObjName);
		if (iObjAlert == -1) continue;
		
		// Is the line within alert proximity?  If not, continue iteration
		iProximity = MathAbs(Bid - dObjPrice) / Point;
		if (iProximity > iObjAlert) continue;

		// Fire the alert and clear alert from description
		sMessage = "Alert triggered: " + Symbol() + " @ " + DoubleToStr(Bid,Digits)  +"."
			+ "  " + iProximity + " pips from " + sObjName + ".";
		if (PopupAlert) Alert(sMessage);
		//if (EmailAlert) SendMail("Alert on " + Symbol(), sMessage);
		
		
		FolderClean(Symbol()+"\\Sent");
		FolderDelete(Symbol()+"\\Shots");
		
		FolderClean(Symbol()+"\\Shots");
		FolderDelete(Symbol()+"\\Sent");
		
		
		FolderClean(Symbol());		
		FolderDelete(Symbol());
		
		FolderCreate(Symbol());
		FolderCreate(Symbol()+"\\Sent");
		FolderCreate(Symbol()+"\\Shots");
		CopyFileW(pathtoMT4+"\\MQL4\\Files\\MT4-AlertMailer.exe", pathtoMT4+"\\MQL4\\Files\\"+Symbol()+"\\MT4-AlertMailer.exe", false);
		
		if (Screenshot) {      
		       
		 //---- make WindowScreenShot and save it to a file
       WindowScreenShot(Symbol()+"\\Shots\Screenshot"+Symbol()+"_"+Bid+".png",imgresolution_x,imgresolution_y);
       
       //---- send email subject and text content to an external text file so the MT4-Mailer.exe can read it and include it in the email
       //---- the below INICONTENT is what will be written to our INI file - this happens dynamically as each screenshot will be different
      string  sentscreenshots = pathtoMT4+"MQL4\Files\\"+Symbol()+"\Sent\\";
      string INICONTENT = "[mail_settings]\r\n"+"SmtpServer = \""+SmtpServer+"\"\r\n"
                          +"FromName=\""+fromName+"\"\r\n"
                          +"FromAddress=\""+fromAddress+"\"\r\n"
                          +"ToAddress=\""+ToAddress+"\"\r\n"
                          +"Subject=\"Alert on "+Symbol()+"\"\r\n"
                          +"Body=\""+sMessage+" Please see attached screenshot for more detail.\"\r\n"
                          +"CcAddress=\""+CcAddress+"\"\r\n"
                          +"BccAddress=\""+BccAddress+"\"\r\n"
                          +"Importance=\"Normal\"\r\n"
                          +"Username=\""+SmtpUsername+"\"\r\n"
                          +"Password=\""+SmtpPassword+"\"\r\n"
                          +"IPPort=\""+SmtpIPPort+"\"\r\n"
                          +"ssl=\""+SSL+"\"\r\n"
                          +"Directoryoffiles=\""+pathtoMT4+"MQL4\Files\\"+Symbol()+"\Shots\\\""+"\r\n"
                          +"ImageFiletype=PNG\r\n"
                          +"DestinationofSent=\""+sentscreenshots+"\"\r\n"
                          +"WorkingDir=\""+pathtoMT4+"MQL4\Files\\"+Symbol()+"\"\r\n";
                         

      string  pathtoINI     = Symbol()+"\Alerter_Mail.INI";
      string buffer = INICONTENT;
      int count = StringLen(buffer);
      WriteFile(pathtoINI,buffer);
  
       
	    //---- Open the the Mailer exe to send the email
	    string  pathtomailer  = pathtoMT4+"MQL4\Files\\"+Symbol()+"\MT4-AlertMailer.exe";
	    Alert(pathtomailer);
	    ShellExecuteW(0, "Open", pathtomailer , "", "", 1);
		
		}
       
		
		// Clear the alert from the object description
		clearObjectAlert(sObjName);
	}

	return(0);
}

double getObjectPrice(string sObjName) {

	int iObjType = ObjectType(sObjName);
	
	// if it's a horizontal line...
	if (iObjType == OBJ_HLINE)
		return(ObjectGet(sObjName,OBJPROP_PRICE1));
	
	// if it's a trend line...
	if (iObjType == OBJ_TREND)
		return(ObjectGetValueByShift(sObjName,0));
		
	// if it's a Rectangle...
	if (iObjType == OBJ_RECTANGLE)
		return(ObjectGetValueByShift(sObjName,0));	
	
	// otherwise...
	return(-1);
}


int getObjectAlert(string sObjName) {

	// looking for pattern "alert_##" at end of obj description
	string 	sObjectDesc		= ObjectDescription(sObjName);
	int 	iPatternOffset 	= StringFind(sObjectDesc,OBJDESC_PATTERN);
	int		iPatternLength	= StringLen(OBJDESC_PATTERN);

	// if pattern not found, no alert for this object
	if (iPatternOffset == -1) 
		return(-1);
	
	// return value after the pattern as number
	//Print("Alert: ", StringSubstr(sObjectDesc,iPatternOffset+iPatternLength));
	return(StrToInteger(StringSubstr(sObjectDesc,iPatternOffset+iPatternLength)));
}

void clearObjectAlert(string sObjName) {

	// strip "alert_*" from end of obj description
	string 	sObjDesc 		= ObjectDescription(sObjName);
	int 	iSubStrOffset 	= StringFind(sObjDesc,"Alert_");
	
	// if found at start of description, clear description
	if (iSubStrOffset == 0) {
		ObjectSetText(sObjName,"");
		return;
	}
	
	// if found further on in desc, strip it from description
	if (iSubStrOffset > 0) {
		ObjectSetText(sObjName,StringSubstr(sObjDesc,0,iSubStrOffset));
		return;
	}
}

void createIndicatorLabel(string sObjName) {
	
	// Set the text
	string sObjText = "Alerts:";
	if (Screenshot) sObjText = sObjText + "  Email Screenshot ON.";
	else            sObjText = sObjText + "  Email Screenshot OFF.";
	if (PopupAlert) sObjText = sObjText + "  Popup Alerts ON.";
	else			sObjText = sObjText + "  Popup Alerts OFF.";
	
	// Create and position the label
	ObjectCreate(sObjName,OBJ_LABEL,0,0,0);
	ObjectSetText(sObjName,sObjText,7,"Verdana",Black);
	ObjectSet(sObjName,OBJPROP_XDISTANCE,230);
	ObjectSet(sObjName,OBJPROP_YDISTANCE,1);
	ObjectSet(sObjName,OBJPROP_CORNER,0);
	
}
	

