//------------------------------------------------------------------------------------------------+
//                                                                                                |
//                                 SonicR FFCal Headlines.mq4                                     |
//                                                                                                |
//------------------------------------------------------------------------------------------------+
#property copyright "Copyright @ 2011 traderathome"
#property link      "email: traderathome@msn.com" 

/*=================================================================================================
Overview:

The SonicR FFCAL Headlines (White or Black).mq4 indicator incorporates a few changes from the
previous SonicR FFCAL Headlines.mq4 indicator that was released 12/01/2010.  A list of the changes
can be found at the bottom of this overview.
                   
This is a trimmed down, muscled up version of the indicator acknowledged below....less code, more 
powerful, and no logging errors.
 
All three impact level events can be displayed (High, Medium, Low).  Prioritization is now fully
automated (see summary comments below).  You color code the text to signify impact levels because
the impact level name is not displayed.  Neither is the Previous/Forecast data.   They're removed 
because it is the timing of news that is important, not contents (lest you try to guess which way
price will go, based on specifics released!).  The vertical display and second alert are removed,
but one alert remains. The display is in the lower left chart corner with a background, and which 
includes four event labels, not just two.

The following is a summary of the enhancements -

 1. Ability to turn the indicator off without deleting it from the chart is added.  For the input 
    "Indicator_On" select "false".  The indicator will retain your chart settings but not display. 
    You can also set up a display range of TFs, so if you change your chart to a TF outside of 
    that range, the indicator will automatically not display.     
 2. The display corner is the lower left of chart and the order of lines is not inverted. 
 3. Event prioritization is fully automated and two more event labels are added to help avoid
    surprises.  When two or more events occur at the same time, only one event of the highest
    impact displays.  When 2nd, 3rd or 4th events are not scheduled, text noting that appears.
 4. Ability to display either normal or bold font and different font styles is added (text size 
    is limited to "8").  With some fonts, especially bold, you may have to increase the width of 
    the background (input provided).
 5. A colored background is provided allowing a more clear FFCal display by hiding the chart  
    beneath.  Its width is adjustable to accomdate longer news titles and larger font styles.
 6. Input "Raise_Display_Override" is added.  If "0" (default) this is inactive.  If ">0" the 
    display and background are raised according to the number input. 
 7. Ability to display Bank Holidays is added. A current day Bank Holiday will remain displayed
    in the first label until the Bank Holiday is over.
 8. Ability to show events for any pair on any chart is added.  For example, you can show CNY
    (China) events on a AUDUSD chart.       
    
What is the "Broker_Watermark" input about?  A broker may have their name appear in pictures of 
MT4 charts.  This Watermark is typically in the lower left corner of the chart picture and will
appear in corner 2 of the chart itself if there are no chart sub-windows being used.  If this is
the case with your broker, for the Watermark to appear withour obscuring the FFCal display in
pictures of your charts, select "true" for this input.  Then if the chart contains no sub-window, 
the background automatically increases in height and the text within is raised.  This makes the
space needed below the FFCal text for the Watermark.

List of Changes From 12/01/2010 Release To Current Release: 
01 - Changes the wording for no more news events.
02 - Adds min/max TF display coding.
03 - Adds ability to show any currency news on chart of any currency pair.
04 - Add "Off" option for Medium Impact items.
05 - Adds "Bank Holiday" to search and prioritization.
06-  Made some adjustments to prioritization code.
07 - Moved DLL Alert code from "start()" section to "init()" section. 
08 - Changed start and end tag strings to accomodate recent Forex Factory .xml file changes. 
   
                                                                       - Traderathome, 05-15-2011
--------------------------------------------------------------------------------------------------
ACKNOWLEDGEMENTS:

derkwehler and other contributors - the core code of the FFCal indicator,
                                    FFCal_v20 dated 07/07/2009, Copyright @ 2006 derkwehler 
                                    http://www.forexfactory.com/showthread.php?t=19293
                                    email: derkwehler@gmail.com  
                                                                     
=================================================================================================*/	
 
 
//+-----------------------------------------------------------------------------------------------+
//| Indicator Global Inputs                                                                       |
//+-----------------------------------------------------------------------------------------------+
#property indicator_chart_window
#property indicator_buffers 1
#property indicator_color1  CLR_NONE

#define TITLE		0
#define COUNTRY   1
#define DATE		2
#define TIME		3
#define IMPACT		4
#define FORECAST	5
#define PREVIOUS	6

/*-------------------------------------------------------------------------------------------------
Suggtested Settings:                 White Charts          Black Charts

Text_Style                           Arial Bold            Arial Bold
FFCal_Title                          Black                 C'188,188,188'
News_High_Impact                     C'220,12,28'          C'243,33,33'
News_Medium_Impact                   RoyalBlue            C'139,163,241'
News_Low_Impact                      Green                 LimeGreen
Bank_Holiday_Color                   DarkOrchid            C'216,109,216'
Remarks_Color                        DarkGray              Gray      
Background_Color_                    White                 Black

-------------------------------------------------------------------------------------------------*/
//global external inputs---------------------------------------------------------------------------
extern string Part_1                          = "Indicator Display Controls:";
extern bool   Indicator_On                    = true;
extern int    Display_Min_TF                  = 5;
extern int    Display_Max_TF                  = 60;
extern string TF_Choices_1                    = "M1 - H4 =  1, 5, 15, 30, 60, 240";
extern string TF_Choices_2                    = "D  W  M =  1440,  10080,  43200";

extern string __                              = "";
extern string Part_2                          = "Headline Display Settings:";
extern string Text_Style                      = "Arial Bold";// choices (Arial Bold, Verdana Bold, etc.  
extern color  FFCal_Title 	                   = Black; 
extern color  High_Impact_News_Color          = C'220,12,28'; //Crimson; //C'218,12,28';              
extern color  Medium_Impact_News_Color        = RoyalBlue; 
extern bool   Medium_Impact_News_On           = true;       
extern color  Low_Impact_News_Color           = Green; 
extern bool   Low_Impact_News_On              = true;
extern color  Bank_Holiday_Color              = DarkOrchid;  //C'175,18,117';
extern bool   Bank_Holiday_On                 = true;
extern color  Remarks_Color                   = DarkGray;     
extern color  Background_Color_               = White; 
extern int    Background_Adjust_Width         = -60;   // +/- #s adjust width to accomdate font, text length, etc.
extern bool   Broker_Watermark                = true;  // Raise display so Watermark will not obscure FFCal text 
extern int    Raise_Display_Override          = 0;     // >0 negates Watermark/AutoRaise settings & raises display
extern int	  Alert_Minutes_Before            = 0;	    // Set to "0" for no Alert
extern int	  Offset_Hours	                   = 1;     // Set to "0" to not adjust time/DST settings from defaults

extern string ___                             = "";
extern string Part_3                          = "Other Currency News Settings:";
extern bool	  Show_USD_News                   = false;  // "true" puts USD news on non-USD pair charts 
extern bool	  Show_EUR_News                   = false; 
extern bool	  Show_GBP_News                   = false;
extern bool	  Show_NZD_News                   = false;
extern bool	  Show_JPY_News                   = false;
extern bool	  Show_AUD_News                   = false;
extern bool	  Show_CAD_News                   = false; 
extern bool	  Show_CHF_News                   = false;
extern bool	  Show_CNY_News                   = false;


//global buffers and variables---------------------------------------------------------------------
bool        FLAG_deinit, skip; 
bool        FLAG_done0, FLAG_done1, FLAG_done2, FLAG_done3; 
bool        FLAG_none0, FLAG_none1, FLAG_none2, FLAG_none3; 
int         BankIdx1;
color       TxtColorNews;
datetime    newsTime;
double   	ExtMapBuffer0[];     	   // Contains (minutes until) each news event
int         WebUpdateFreq   = 240;     // 240 Minutes between web updates to not overload FF server
int 	      xmlHandle, BoEvent, finalend, end, begin, minsTillNews, tmpMins, idxOfNext, dispMinutes[9];
int         newsIdx, next, nextNewsIdx, dispMins, Days, Hours, Mins;
int         F1,F2,i,curX,curY,W,Box,x1,x2,x3,y1,y2,y3,EventSpacer,TitleSpacer,TxtSize,index;       
static int	PrevMinute      = -1;
static bool NeedToGetFile   = false;
string 		xmlFileName;
string	   sUrl = "http://www.forexfactory.com/ff_calendar_thisweek.xml"; //original
string   	myEvent,mainData[100][7], sData, csvoutput, sinceUntil, TimeStr;
string    	pair, cntry1, cntry2, dispTitle[9], dispCountry[9], dispImpact[9];
string 	   sTags[7] = { "<title>", "<country>", "<date><![CDATA[", "<time><![CDATA[", "<impact><![CDATA[", "<forecast><![CDATA[", "<previous><![CDATA[" };
string 	   eTags[7] = { "</title>", "</country>", "]]></date>", "]]></time>", "]]></impact>", "]]></forecast>", "]]></previous>" };
string      g       = "gggg";     
string      box1    = "[FFCal] Box1";
string      box2    = "[FFCal] Box2";
string      News1   = "[FFCal] News1";
string      News2   = "[FFCal] News2";
string      News3   = "[FFCal] News3";
string      News4   = "[FFCal] News4";
string      Title   = "FOREX FACTORY CALENDAR HEADLINES:"; 
string      Sponsor = "[FFCal] Sponsor";  

//+-----------------------------------------------------------------------------------------------+
//| Indicator Initialization                                                                      |
//+-----------------------------------------------------------------------------------------------+
int init()
   {
	//Make sure we are connected.  Otherwise exit.   
   //With the first DLL call below, the program will exit (and stop) automatically after one alert. 
   if ( !IsDllsAllowed() ) 
      {
      Alert("SonicR FFCal Headlines: Check 'Allow DLL Imports'");   
      } 
         
   FLAG_deinit = false;
    
	SetIndexBuffer(0, ExtMapBuffer0);
   SetIndexStyle(0, DRAW_NONE);		
   IndicatorShortName("FFCal");  	  	   	  		
   	  		
	return(0);
   }
   
//+-----------------------------------------------------------------------------------------------+
//| Indicator De-initialization                                                                   |
//+-----------------------------------------------------------------------------------------------+
int deinit()
   {         
   int obj_total= ObjectsTotal();  
   for (i= obj_total; i>=0; i--) {
      string name= ObjectName(i);
      if (StringSubstr(name,0,7)=="[FFCal]") {ObjectDelete(name);}} 
 	  
	//If xml file exists we need to delete it 
	xmlFileName = GetXmlFileName();
	//File does not exist if FileOpen returns -1 	
	xmlHandle = FileOpen(xmlFileName, FILE_BIN|FILE_READ|FILE_WRITE);
	if (xmlHandle >= 0)
	   {
		//Since file exists, close and delete it
		FileClose(xmlHandle);		
		FileDelete(xmlFileName);
	   } 
	   
	//Comment (" "); 	     
	return(0);
   }
  
//+-----------------------------------------------------------------------------------------------+
//| Indicator Start                                                                               |
//+-----------------------------------------------------------------------------------------------+  
int start()
   {
   //If Indicator is "Off" or chart is out of range deinitialize only once, not every tick---------
   if((!Indicator_On) || ((Period() < Display_Min_TF) || (Period() > Display_Max_TF)))        
      {
      if (!FLAG_deinit)  {deinit(); FLAG_deinit = true;} 
      return(0);
      }    
     
   //Otherwise indicator is "On", chart TF is in display range.  Proceed---------------------------  
   FLAG_deinit = false;
   
	//Check if the XML file exists.  If not, set a flag showing the need to get it.
	xmlFileName = GetXmlFileName();
	xmlHandle = FileOpen(xmlFileName, FILE_BIN|FILE_READ);
   //File exists if FileOpen return is >=0 	
	if (xmlHandle >= 0) {FileClose(xmlHandle); NeedToGetFile = false;}
	//File does not exist if FileOpen return is -1 	
	else NeedToGetFile = true;
	
	//----------------------------------------------------------------------------------------------
	//WebUpdates New method: Use global variables so that when put on multiple charts, it 
	//will not update overly often; only first time and every 4 hours	per "WebUpdateFreq".		
  	if (NeedToGetFile || GlobalVariableCheck("LastUpdateTime") == false || 
  		(TimeCurrent() - GlobalVariableGet("LastUpdateTime")) > WebUpdateFreq)
		{	
		GrabWeb(sUrl, sData);		
   	//if time for web update, delete existing file if it exists	
	   xmlFileName = GetXmlFileName();
	   xmlHandle = FileOpen(xmlFileName, FILE_BIN|FILE_READ|FILE_WRITE);
	   //File exists if FileOpen return >=0. 
	   if (xmlHandle >= 0) {FileClose(xmlHandle); FileDelete(xmlFileName);}	   		

		//Open new XML.  Write the ForexFactory page contents to a .htm file.  Close new XML.
		xmlHandle = FileOpen(xmlFileName, FILE_BIN|FILE_WRITE);		   
		FileWriteString(xmlHandle, sData, StringLen(sData));
		FileClose(xmlHandle);
		
		//Find the XML end tag to ensure a complete page was downloaded.
		end = StringFind(sData, "</weeklyevents>", 0);
		//End of file tag is not found if return -1 (or, "end <=0" in this case).
		if (!end >= 0) {Alert("FFCal Error - Web page download was not complete!"); return(false);}
		else {GlobalVariableSet("LastUpdateTime", TimeCurrent());} // set global to time of last update			
		}
	//----------------------------------------------------------------------------------------------

	//Perform remaining checks once per minute (Refreshing News from XML file)
	if (Minute() == PrevMinute) return (true);
	PrevMinute = Minute();

	//Init the buffer array to zero just in case
	ArrayInitialize(ExtMapBuffer0, 0);
	
	//Open, read and close the XML file
	xmlHandle = FileOpen(xmlFileName, FILE_BIN|FILE_READ);
	//Avg. file length == ~7K, so 65536 should always read whole file
	sData = FileReadString(xmlHandle, 65536);	
   if (StringLen(sData) < FileSize(xmlHandle)) sData = sData + FileReadString(xmlHandle, FileSize(xmlHandle));		
	if (xmlHandle > 0) FileClose(xmlHandle);

	//Get the currency pair, and split it into the two countries
	pair = Symbol();
	cntry1 = StringSubstr(pair, 0, 3);
	cntry2 = StringSubstr(pair, 3, 3);

	//Clear prioritization data
	BankIdx1   = 0; 
	FLAG_done0 = false; 
   FLAG_done1 = false;  
   FLAG_done2 = false;
   FLAG_done3 = false;
   FLAG_none0 = false;    
   FLAG_none1 = false; 
   FLAG_none2 = false;
   FLAG_none3 = false;  
	for (i=0; i<=9; i++)
	   {
	   dispTitle[i]   = "";
	   dispCountry[i] = "";
	   dispImpact[i] 	= "";
	   dispMinutes[i]	= 0;	
      }

	//Parse the XML file looking for an event to report		
	newsIdx = 0;
	nextNewsIdx = -1;	
	tmpMins = 10080;	// (a week)
	BoEvent = 0;
	while (true)
   	{
		BoEvent = StringFind(sData, "<event>", BoEvent);
		if (BoEvent == -1) break;			
		BoEvent += 7;	
		next = StringFind(sData, "</event>", BoEvent);
		if (next == -1) break;	
		myEvent = StringSubstr(sData, BoEvent, next - BoEvent);
		BoEvent = next;		
		begin = 0;
		skip = false;
		for (i=0; i < 7; i++)
		   {
			mainData[newsIdx][i] = "";
			next = StringFind(myEvent, sTags[i], begin);			
			// Within this event, if tag not found, then it must be missing; skip it
			if (next == -1) continue;
			else
			   {
				// We must have found the sTag okay...
				begin = next + StringLen(sTags[i]);		   	// Advance past the start tag
				end = StringFind(myEvent, eTags[i], begin);	// Find start of end tag
				//Get data between start and end tag
				if (end > begin && end != -1) {mainData[newsIdx][i] = StringSubstr(myEvent, begin, end - begin);}
			   }
		   }//End "for" loop
	
		//Test against filters that define whether we want to skip this particular announcement
      //Look for a Bank Holiday for current day
      
		if ( (Bank_Holiday_On &&  BankIdx1 == 0) &&
			(mainData[newsIdx][IMPACT] == "Holiday") &&			   		   
		   ((cntry1 == mainData[newsIdx][COUNTRY]) || 
		   (cntry2 == mainData[newsIdx][COUNTRY]) ||
		   (Show_USD_News && mainData[newsIdx][COUNTRY] == "USD") || 
			(Show_EUR_News && mainData[newsIdx][COUNTRY] == "EUR") || 
			(Show_GBP_News && mainData[newsIdx][COUNTRY] == "GBP") || 
			(Show_NZD_News && mainData[newsIdx][COUNTRY] == "NZD") || 
			(Show_JPY_News && mainData[newsIdx][COUNTRY] == "JPY") || 
			(Show_AUD_News && mainData[newsIdx][COUNTRY] == "AUD") || 
			(Show_CAD_News && mainData[newsIdx][COUNTRY] == "CAD") || 
			(Show_CHF_News && mainData[newsIdx][COUNTRY] == "CHF") || 
			(Show_CNY_News && mainData[newsIdx][COUNTRY] == "CNY") ))
		   {
		   newsTime = StrToTime(MakeDateTime(mainData[newsIdx][DATE], mainData[newsIdx][TIME]));
			minsTillNews = (newsTime - TimeGMT()) / 60;			
			//Only capture the current day Bank Holiday
			if ((minsTillNews > -1440) && (minsTillNews <= 0)) 
			   {
			   BankIdx1       = 1;			      
			   dispCountry[7] = mainData[newsIdx][COUNTRY];
			   dispMinutes[7] = minsTillNews;
			   dispTitle[7]	=  "Start " + mainData[newsIdx][TITLE];
			   dispImpact[7]  = "Holiday";	
				}			   				   
		   }
		   						
		else if ((cntry1 != mainData[newsIdx][COUNTRY] && cntry2 != mainData[newsIdx][COUNTRY]) &&
			((!Show_USD_News || mainData[newsIdx][COUNTRY] != "USD") && 
			(!Show_EUR_News || mainData[newsIdx][COUNTRY] != "EUR") && 
			(!Show_GBP_News || mainData[newsIdx][COUNTRY] != "GBP") && 
			(!Show_NZD_News || mainData[newsIdx][COUNTRY] != "NZD") && 
			(!Show_JPY_News || mainData[newsIdx][COUNTRY] != "JPY") && 
			(!Show_AUD_News || mainData[newsIdx][COUNTRY] != "AUD") && 
			(!Show_CAD_News || mainData[newsIdx][COUNTRY] != "CAD") && 
			(!Show_CHF_News || mainData[newsIdx][COUNTRY] != "CHF") && 
			(!Show_CNY_News || mainData[newsIdx][COUNTRY] != "CNY")))
			{skip = true;}	
			
		else if ((!Medium_Impact_News_On) && 
		   (mainData[newsIdx][IMPACT] == "Medium"))
		   {skip = true;} 
		   														   
		else if ((!Low_Impact_News_On) && 
		   (mainData[newsIdx][IMPACT] == "Low"))
		   {skip = true;} 
		   
		else if ((!Bank_Holiday_On) &&		
	      (mainData[newsIdx][IMPACT] == "Holiday"))
			{skip = true;}	
			
   	else if ((mainData[newsIdx][TIME] == "All Day" && mainData[newsIdx][TIME] == "") || 
		   (mainData[newsIdx][TIME] == "Tentative" && mainData[newsIdx][TIME] == "")     ||
		  	(mainData[newsIdx][TIME] == ""))
		  	{skip = true;}			  	
		    				  	 				  	 
		//If not skipping this event, then log time to event it into ExtMapBuffer0
		if (!skip)
		   {   
			//If we got this far then we need to calc the minutes until this event
			//First, convert the announcement time to seconds (in GMT)
			newsTime = StrToTime(MakeDateTime(mainData[newsIdx][DATE], mainData[newsIdx][TIME]));			
			// Now calculate the minutes until this announcement (may be negative)
			minsTillNews = (newsTime - TimeGMT()) / 60;
			
         //If this is a Bank Holiday current or past event, skip it by changing time to 2 days back
         if ((StringFind(mainData[newsIdx][TITLE], "Bank Holiday", StringLen(mainData[newsIdx][TITLE])-12) != -1) &&
            (minsTillNews <= 0))
            {
            minsTillNews = minsTillNews - 2880;
            }
            
			//At this point, only events applicable to the pair ID/Symbol are being processed:
			//Find the most recent past event.  Do this by incrementing idxOfNext for each event 
			//with a past time, (i.e. minsTillNews < 0).  When coming upon the first event with 
			//minsTillNews > 0, idxOfNext is not incremented, and therefore continues to be for 
			//the most recent past event.  It does not get incremented again until the absolute 
			//value of the time since this most recent past event exceeds the time to the next
			//future event.
			
			if (minsTillNews < 0 || MathAbs(tmpMins) > minsTillNews)	{idxOfNext = newsIdx; tmpMins	= minsTillNews;}	
						
			//Do alert if user has enabled
			if (Alert_Minutes_Before != 0 && minsTillNews == Alert_Minutes_Before)
				Alert(Alert_Minutes_Before, " minutes until news for ", pair, ": ", mainData[newsIdx][TITLE]);
						
			//ExtMapBuffer0 contains the time UNTIL each announcement (can be negative)
			//e.g. [0] = -372; [1] = 25; [2] = 450; [3] = 1768 (etc.)
			ExtMapBuffer0[newsIdx] = minsTillNews;
			
			newsIdx++;
		   }//End "skip" routine
	   }//End "while" routine
	   
	//----------------------------------------------------------------------------------------------
   //Cycle thru the range of "newsIdx" prioritizing events for display.
	for (i=0; i < newsIdx; i++)
	   {
      //The 1st event to be displayed is either a past event, or an upcoming event, whichever is the
      //most close in time.  If the 1st event is a past event, then look at the two previous past events.
      //For any of them that occurred at the same time as the 1st event, choose the one with the highest
      //impact and display it as the 1st event.
      
      //Get 4th previous item:
      if (i == idxOfNext-3) 
         {    
			dispTitle[6]	   = mainData[i][TITLE];
			dispCountry[6] 	= mainData[i][COUNTRY];
			dispImpact[6]  	= mainData[i][IMPACT];
			dispMinutes[6] 	= ExtMapBuffer0[i];      
         }      
      //Get 3rd previous item:
      if (i == idxOfNext-2) 
         {      
			dispTitle[5]	   = mainData[i][TITLE];
			dispCountry[5] 	= mainData[i][COUNTRY];
			dispImpact[5]  	= mainData[i][IMPACT];
			dispMinutes[5] 	= ExtMapBuffer0[i];      
         }
      //Get 2nd previous item:   
      if (i == idxOfNext-1) 
         {   
			dispTitle[4]	   = mainData[i][TITLE];
			dispCountry[4] 	= mainData[i][COUNTRY];
			dispImpact[4]  	= mainData[i][IMPACT];
			dispMinutes[4] 	= ExtMapBuffer0[i];      
         }  
      //Get previous/current items:        
      if (i == idxOfNext)  
         {
         dispTitle[0]	   = mainData[i][TITLE];
			dispCountry[0] 	= mainData[i][COUNTRY];
			dispImpact[0]  	= mainData[i][IMPACT];
			dispMinutes[0] 	= ExtMapBuffer0[i];
         //If idxOfNext is a previous event, then compare to 4th, 3rd and 2nd previous items:  			         
         if (dispMinutes[0] <= 0) 
            { 
            //if time [0] = [6] and [6] is  >= impact than [0], then [6] becomes 1st event [0]: 
	         if ((dispMinutes[0] == dispMinutes[6]) &&	
	         ((dispImpact[0] == dispImpact[6]) ||	
	         (dispImpact[0]  == "Medium" && dispImpact[6] == "High")  ||
			   (dispImpact[0]  == "Low"    && dispImpact[6] == "High")  ||
			   (dispImpact[0]  == "Low"    && dispImpact[6] == "Medium")))
		 	      {		 	   
		      	dispTitle[0]   = dispTitle[6];
			      dispCountry[0] = dispCountry[6];
			      dispImpact[0]  = dispImpact[6];
			      dispMinutes[0] = dispMinutes[6];						   
               }                              									
		      //if time [0] = [5] and [5] is  >= impact than [0], then [5] becomes 1st event [0]: 
	         else if ((dispMinutes[0] == dispMinutes[5]) &&	
	         ((dispImpact[0] == dispImpact[5]) ||	
	         (dispImpact[0]  == "Medium" && dispImpact[5] == "High")  ||
			   (dispImpact[0]  == "Low"    && dispImpact[5] == "High")  ||
			   (dispImpact[0]  == "Low"    && dispImpact[5] == "Medium")))
		 	      {		 	   
		      	dispTitle[0]   = dispTitle[5];
			      dispCountry[0] = dispCountry[5];
			      dispImpact[0]  = dispImpact[5];
			      dispMinutes[0] = dispMinutes[5];						   
               }
	         //if time [0] = [4] and [4] is >= impact than [0], then [4] becomes 1st event [0]:
	         else if ((dispMinutes[0] == dispMinutes[4]) &&	
	         ((dispImpact[0] == dispImpact[4]) ||	
	         (dispImpact[0]  == "Medium" && dispImpact[4] == "High")  ||
			   (dispImpact[0]  == "Low"    && dispImpact[4] == "High")  ||
			   (dispImpact[0]  == "Low"    && dispImpact[4] == "Medium")))
		 	      {		 	   
		   	   dispTitle[0]	= dispTitle[4];
			      dispCountry[0] = dispCountry[4];
			      dispImpact[0]  = dispImpact[4];
			      dispMinutes[0] = dispMinutes[4];
			      }						   
            }
         }   
         
		//---------------------------------------------------------------- 	            
      //Now that 1st event[0] is initialized, go thru rest of items, prioritizing.  
		if (i >= idxOfNext+1)  
		   {  
         dispTitle[6]	= mainData[i][TITLE];
			dispCountry[6] = mainData[i][COUNTRY];
			dispImpact[6]  = mainData[i][IMPACT];
			dispMinutes[6] = ExtMapBuffer0[i];
			//If 1st event [0] is not done, and         		   
			//if time [i] = [0] and [i] has >= impact than [0], then [i] becomes 1st event [0].
	   	//if time [i] > [0] then initialize [i] as 2nd event [1]: 
	   	if (!FLAG_done0) 
	   	   { 
			   if ((dispMinutes[0] == dispMinutes[6]) && 			
	            ((dispImpact[0]  == "Medium" && dispImpact[6] == "High")  ||
			      (dispImpact[0]   == "Low"    && dispImpact[6] == "High")  || 
			      (dispImpact[0]   == "Low"    && dispImpact[6] == "Medium")))
		 	      {
               dispTitle[0]	  = dispTitle[6];
			      dispCountry[0]   = dispCountry[6];
			      dispImpact[0]    = dispImpact[6];
			      dispMinutes[0]   = dispMinutes[6];		 	   		 	   		 	   			
			      }
		      else if (dispMinutes[0] < dispMinutes[6])	      
		         {
               dispTitle[1]	  = dispTitle[6];
			      dispCountry[1]   = dispCountry[6];
			      dispImpact[1]    = dispImpact[6];
			      dispMinutes[1]   = dispMinutes[6];
			      FLAG_done0 = true;
			      continue;
		         }
		      }
		   //If 1st event [0] is done, but 2nd event [1] is not done, and   
			//if time [i] = [1] and [i] has >= impact than [1], then [i] becomes 2nd event [1].
			//if time [i] > [1] then intialize [i] as 3rd event [2]: 
         if ((FLAG_done0) && (!FLAG_done1)) 
		      {			 			   	
			   if ((dispMinutes[1] == dispMinutes[6]) && 		
	            ((dispImpact[1]  == "Medium" && dispImpact[6] == "High")  ||
			      (dispImpact[1]   == "Low"    && dispImpact[6] == "High")  || 
			      (dispImpact[1]   == "Low"    && dispImpact[6] == "Medium")))
		 	      {
               dispTitle[1]	   = dispTitle[6];
			      dispCountry[1] 	= dispCountry[6];
			      dispImpact[1]  	= dispImpact[6];
			      dispMinutes[1] 	= dispMinutes[6];	
			      }
			   else if (dispMinutes[1] < dispMinutes[6])			   		    
			      {
               dispTitle[2]	   = dispTitle[6];
			      dispCountry[2] 	= dispCountry[6];
			      dispImpact[2]  	= dispImpact[6];
			      dispMinutes[2] 	= dispMinutes[6];					      
			      FLAG_done1 = true;
			      continue;
			      }   
			   }
	      //If 1st event [0] and 2nd event [1] are done, but 3rd event [2] is not, and
			//if time [i] = [2] and [i] has >= impact than [2], then [i] becomes 3rd event [2].
		   //if time [i] > [2] then intialize [i] as 4th event [3]:  	
         if ((FLAG_done0) && (FLAG_done1) && (!FLAG_done2)) 
		      {						   
			   if ((dispMinutes[2] == dispMinutes[6]) && 		
	            ((dispImpact[2]  == "Medium" && dispImpact[6] == "High")  ||
			      (dispImpact[2]   == "Low"    && dispImpact[6] == "High")  || 
			      (dispImpact[2]   == "Low"    && dispImpact[6] == "Medium")))
		 	      {
               dispTitle[2]	   = dispTitle[6];
			      dispCountry[2] 	= dispCountry[6];
			      dispImpact[2]  	= dispImpact[6];
			      dispMinutes[2] 	= dispMinutes[6];		   			        		 	   		 	   		 	   			
			      }
			   else if (dispMinutes[2] < dispMinutes[6]) 		    
			      {
               dispTitle[3]	   = dispTitle[6];
			      dispCountry[3] 	= dispCountry[6];
			      dispImpact[3]  	= dispImpact[6];
			      dispMinutes[3] 	= dispMinutes[6];					      
			      FLAG_done2 = true;
			      continue;
			      }  
			   }
         //If 1st, 2nd, and 3rd events are done, but 4th event [3] is not, and
			//if time [i] = [3] and [i] has >= impact than [3], then [i] becomes 4th event [3].
			//Otherwise, prioritizing is finished:  	
         if ((FLAG_done0) && (FLAG_done1) && (FLAG_done2) && (!FLAG_done3)) 
		      {						   
			   if ((dispMinutes[3] == dispMinutes[6])  &&	
	            ((dispImpact[3]  == "Medium" && dispImpact[6] == "High")  ||
			      (dispImpact[3]   == "Low"    && dispImpact[6] == "High")  || 
			      (dispImpact[3]   == "Low"    && dispImpact[6] == "Medium")))
		 	      {
               dispTitle[3]	   = dispTitle[6];
			      dispCountry[3] 	= dispCountry[6];
			      dispImpact[3]  	= dispImpact[6];
			      dispMinutes[3] 	= dispMinutes[6];	  			        		 	   		 	   		 	   			
			      }
			   //Prioritizing is finished:    
			   else
			      {
			      FLAG_done3 = true;
			      } 			      			   			   
			   }
						    			
 			//If all four event items are prioritized, exit loop.	   			   							   			   
		   if ((FLAG_done0) && (FLAG_done1) && (FLAG_done2) && (FLAG_done3)) {break;} 
			}
			  
	   }//End prioritizing "for" loop	
	   
	   //Next, determine if any events are out of sequence in time, or are duplicates in title 
	   //and are within the same 24 hour period.  If so, eliminate the higher event item by
	   //setting the flag to not show the item.
	   //Check 1st and 2nd items.  
		if (((dispTitle[0]==dispTitle[1]) && (dispMinutes[0]+ 1440 > dispMinutes[1])) ||
		   (dispMinutes[0] > dispMinutes[1]))
			{
			{FLAG_none1  = true;}	
			}			 	   	
      //Also check 1st and 3rd, and 2nd and 3rd items. 
		if (((dispTitle[0]==dispTitle[2]) && (dispMinutes[0]+ 1440 > dispMinutes[2])) ||  
			((dispTitle[1]==dispTitle[2]) && (dispMinutes[1]+ 1440 > dispMinutes[2]))  ||
			(dispMinutes[0] > dispMinutes[2]) || (dispMinutes[1] > dispMinutes[2]))
			{
			{FLAG_none2  = true;}	
			} 				     
      //Also check 1st and 4th, and 3rd and 4th items. 
		if (((dispTitle[0]==dispTitle[3]) && (dispMinutes[0]+ 1440 > dispMinutes[3])) ||  
			((dispTitle[2]==dispTitle[3]) && (dispMinutes[2]+ 1440 > dispMinutes[3]))  ||
			(dispMinutes[0] > dispMinutes[3]) || (dispMinutes[2] > dispMinutes[3]))
			{
			{FLAG_none3  = true;}	
			}
			
	   //Check if 1st event[0] is more than half a day old and no 2nd event is scheduled.
	   //If so, eliminate the 1st event[0].	
	   if ((dispMinutes[0] < -720) && (dispMinutes[1] == 0 )) 
			{
			{FLAG_none0  = true;}	
			}
					
		//Be sure no "FLAG_none" remains false if a lower one turned to true
		if (FLAG_none0) 
		   {
		   FLAG_none1  = true;
		   FLAG_none2  = true;
		   FLAG_none3  = true;
		   }
		else if (FLAG_none1) 
		   {
		   FLAG_none2  = true;
		   FLAG_none3  = true;
		   }
		else if (FLAG_none2) 
		   {
		   FLAG_none3  = true;
		   }
	
		//Be sure to "FLAG_none" any with no country tag
		if (dispCountry[0] == "") {FLAG_none0 = true;}
		if (dispCountry[1] == "") {FLAG_none1 = true;}
		if (dispCountry[2] == "") {FLAG_none2 = true;}
		if (dispCountry[3] == "") {FLAG_none3 = true;}
		        
		//Check for current day Bank Holiday.  If there is one, then move all
      //events up one tier and insert the Bank Holiday into 1st event.
      if (BankIdx1 == 1)
		   {      
         dispTitle[3]	   = dispTitle[2];
			dispCountry[3] 	= dispCountry[2];
			dispImpact[3]  	= dispImpact[2];
			dispMinutes[3] 	= dispMinutes[2];
			FLAG_none3        = FLAG_none2;
		  
			dispTitle[2]	   = dispTitle[1];
			dispCountry[2] 	= dispCountry[1];
			dispImpact[2]  	= dispImpact[1];
			dispMinutes[2] 	= dispMinutes[1];
			FLAG_none2        = FLAG_none1;
			     	
         dispTitle[1]	   = dispTitle[0];
			dispCountry[1] 	= dispCountry[0];
			dispImpact[1]  	= dispImpact[0];
			dispMinutes[1] 	= dispMinutes[0];
			FLAG_none1        = FLAG_none0;
			     
         dispTitle[0]	   = dispTitle[7];
			dispCountry[0]    = dispCountry[7];
			dispImpact[0]  	= dispImpact[7];
			dispMinutes[0]    = dispMinutes[7];
			FLAG_none0        = false;
			}
      
	//----------------------------------------------------------------------------------------------					
	OutputToChart();		
	return (0);
   }
   
//+-----------------------------------------------------------------------------------------------+
//| Subroutine to get the name of the ForexFactory .xml file                                      |
//+-----------------------------------------------------------------------------------------------+    
string GetXmlFileName()
   {
	return (Month() + "-" + Day() + "-" + Year() + "-" + Symbol() + Period() + "-" + "FFCal.xml");
   }

//+-----------------------------------------------------------------------------------------------+
//| Indicator Routine For Normal Display                                                          |
//+-----------------------------------------------------------------------------------------------+  
void OutputToChart()
   {
   //Do background--------------------------------------------------------------------------------- 
   TxtSize     = 8;  
   TitleSpacer = 7;
   EventSpacer = 4; 
   curX        = 3; //7,6,5,0                  	
	x1          = 0; 
	y1          = 1; 
	y2          = 1;	     
	W           = WindowsTotal( );
	      
   //Set up to do background boxes 	               
   if(Broker_Watermark && W ==1) 
      {
      curY = 9;  //6; 
      Box  = 67;  //65;  //62;  //56;//60
      x2   = 115+Background_Adjust_Width; //x2 range from "115" setting = -113/+205          
      curY = curY+12;
      } 
   else
      {
      curY = 4; 
      Box  = 54;  //53;  //46;//50
      x2   = 163+Background_Adjust_Width; //x2 range from "163" setting = -162/+101 
      }
   if(Raise_Display_Override >0)
      {     
      curY = Raise_Display_Override + 4; 
      Box  = 54;  //44;//50, 46, 
      x2   = 163+Background_Adjust_Width; //x2 range from "163" setting = -162/+101         
      y1   = Raise_Display_Override;     
      y2   = Raise_Display_Override;
      }

   //Do labels: 
   //Do fourth event description line--------------------------------------------------------------- 	           
   sinceUntil = "until ";
   dispMins = dispMinutes[3]+1;
	if (dispMinutes[3] <= 0) {dispMins = dispMins - 1; sinceUntil = "since "; dispMins *= -1;} //"*= -1" = multiply by "-1"  	
   if (dispMins < 60) {TimeStr = dispMins + " mins ";}
	else // time is 60 minutes or more
	   {
		Hours = MathRound(dispMins / 60);
	   Mins = dispMins % 60;
	   if (Hours < 24) // less than a day: show hours and minutes 
		   {
			TimeStr = Hours + " hrs " + Mins + " mins ";
		   }
		else // days, hours, and minutes
		  	{
		  	Days = MathRound(Hours / 24);
		 	Hours = Hours % 24;
		  	TimeStr = Days + " days " + Hours + " hrs " + Mins + " mins ";
		  	}
	   }               	
   index = StringFind(TimeStr+sinceUntil+dispCountry[3], "since  mins", 0);  
   TxtColorNews = ImpactToColor(dispImpact[3]);	   		      	
	ObjectDelete(News4);       	
   ObjectCreate(News4, OBJ_LABEL, 0, 0, 0);
		if((index != -1) || (FLAG_none3)) {	        
		   ObjectSetText(News4, "(4)  Additional news events not scheduled", TxtSize, Text_Style, Remarks_Color);}	           		                		            			            	            		   	   
	   else {
		   ObjectSetText(News4, TimeStr + sinceUntil + dispCountry[3] + ": " + dispTitle[3], TxtSize, Text_Style, TxtColorNews);}		   		  
	ObjectSet(News4, OBJPROP_CORNER, 2);
	ObjectSet(News4, OBJPROP_XDISTANCE, curX);
	ObjectSet(News4, OBJPROP_YDISTANCE, curY); 	   	   	
   curY = curY + TxtSize + EventSpacer;        
         
   //Do third event description line--------------------------------------------------------------- 	           
   sinceUntil = "until ";
   dispMins = dispMinutes[2]+1;
	if (dispMinutes[2] <= 0) {dispMins = dispMins - 1; sinceUntil = "since "; dispMins *= -1;} //"*= -1" = multiply by "-1"  	
   if (dispMins < 60) {TimeStr = dispMins + " mins ";}
	else // time is 60 minutes or more
	   {
		Hours = MathRound(dispMins / 60);
	   Mins = dispMins % 60;
	   if (Hours < 24) // less than a day: show hours and minutes 
		   {
			TimeStr = Hours + " hrs " + Mins + " mins ";
		   }
		else // days, hours, and minutes
		  	{
		  	Days = MathRound(Hours / 24);
		 	Hours = Hours % 24;
		  	TimeStr = Days + " days " + Hours + " hrs " + Mins + " mins ";
		  	}
	   }               	
   index = StringFind(TimeStr+sinceUntil+dispCountry[2], "since  mins", 0); 		      	
   TxtColorNews = ImpactToColor(dispImpact[2]);	 	      	
	ObjectDelete(News3);       	
   ObjectCreate(News3, OBJ_LABEL, 0, 0, 0);
		if((index != -1) || (FLAG_none2)) {	        
		   ObjectSetText(News3, "(3)  Additional news events not scheduled", TxtSize, Text_Style, Remarks_Color);}	           		                		            			            	            		   	   
	   else {
		   ObjectSetText(News3, TimeStr + sinceUntil + dispCountry[2] + ": " + dispTitle[2], TxtSize, Text_Style, TxtColorNews);}		   		  
	ObjectSet(News3, OBJPROP_CORNER, 2);
	ObjectSet(News3, OBJPROP_XDISTANCE, curX);
	ObjectSet(News3, OBJPROP_YDISTANCE, curY); 	   	   	
   curY = curY + TxtSize + EventSpacer;     
           
	//Do second event description line-------------------------------------------------------------- 	           
   sinceUntil = "until ";
   dispMins = dispMinutes[1]+1;
	if (dispMinutes[1] <= 0) {dispMins = dispMins - 1; sinceUntil = "since "; dispMins *= -1;} //"*= -1" = multiply by "-1"  	
   if (dispMins < 60) {TimeStr = dispMins + " mins ";}
	else // time is 60 minutes or more
	   {
	   Hours = MathRound(dispMins / 60);
	   Mins = dispMins % 60;
	   if (Hours < 24) // less than a day: show hours and minutes 
		   {
		   TimeStr = Hours + " hrs " + Mins + " mins ";
		   }
		else // days, hours, and minutes
		   {
		   Days = MathRound(Hours / 24);
			Hours = Hours % 24;
			TimeStr = Days + " days " + Hours + " hrs " + Mins + " mins ";
		   }
	   }               	
	index = StringFind(TimeStr+sinceUntil+dispCountry[1], "since  mins", 0); 		      	
   TxtColorNews = ImpactToColor(dispImpact[1]);	 	      	
	ObjectDelete(News2);       	
   ObjectCreate(News2, OBJ_LABEL, 0, 0, 0);
		if((index != -1) || (FLAG_none1)) {		       
		   ObjectSetText(News2, "(2)  Additional news events not scheduled", TxtSize, Text_Style, Remarks_Color);}	           		                		            			            	            		   	   
	   else {
		   ObjectSetText(News2, TimeStr + sinceUntil + dispCountry[1] + ": " + dispTitle[1], TxtSize, Text_Style, TxtColorNews);}		  
	ObjectSet(News2, OBJPROP_CORNER, 2);
   ObjectSet(News2, OBJPROP_XDISTANCE, curX);
	ObjectSet(News2, OBJPROP_YDISTANCE, curY); 	   	   	
   curY = curY + TxtSize + EventSpacer;     
         
	//Do first event description line---------------------------------------------------------------  
	//If time is 0 or negative, we want to say "xxx mins SINCE ... news event", else say "UNTIL ... news event"
	sinceUntil = "until ";
	dispMins = dispMinutes[0]+1;
	if (dispMinutes[0] <= 0) {dispMins = dispMins - 1; sinceUntil = "since "; dispMins *= -1;}	      
	if (dispMins < 60) {TimeStr = dispMins + " mins ";}
	else // time is 60 minutes or more
	   {
		Hours = MathRound(dispMins / 60);
		Mins = dispMins % 60;
		if (Hours < 24) // less than a day: show hours and minutes
		   {
		   TimeStr = Hours + " hrs " + Mins + " mins ";
		   }
		else  // days, hours, and minutes
		   {
		   Days = MathRound(Hours / 24);
			Hours = Hours % 24;
			TimeStr = Days + " days " + Hours + " hrs " + Mins + " mins ";
		   }
	   }	  		         
	index = StringFind(TimeStr+sinceUntil+dispCountry[0], "since  mins", 0); //Comment (index);	
	TxtColorNews = ImpactToColor(dispImpact[0]);	       	   
	ObjectDelete(News1);		         	    
	ObjectCreate(News1, OBJ_LABEL, 0, 0, 0);
		if((index != -1) || (FLAG_none0)) {	      
		   ObjectSetText(News1, "(1)  Additional news events not scheduled", TxtSize, Text_Style, Remarks_Color);}			                  	         		         	
		else {
	   	ObjectSetText(News1, TimeStr + sinceUntil + dispCountry[0] + ": " + dispTitle[0], TxtSize, Text_Style, TxtColorNews);}
	ObjectSet(News1, OBJPROP_CORNER, 2);
	ObjectSet(News1, OBJPROP_XDISTANCE, curX);
	ObjectSet(News1, OBJPROP_YDISTANCE, curY);        	
   curY = curY + TxtSize + TitleSpacer;    
   	       
   //Finish with title-----------------------------------------------------------------------------
	ObjectDelete(Sponsor);         	     	         	
	ObjectCreate(Sponsor, OBJ_LABEL, 0, 0, 0);
 	ObjectSetText(Sponsor, Title, TxtSize, Text_Style, FFCal_Title);
	ObjectSet(Sponsor, OBJPROP_CORNER, 2);
	ObjectSet(Sponsor, OBJPROP_XDISTANCE, curX);
	ObjectSet(Sponsor, OBJPROP_YDISTANCE, curY);               

	return (0);
   }

//+-----------------------------------------------------------------------------------------------+
//| Indicator Subroutine For Impact Color                                                         |
//+-----------------------------------------------------------------------------------------------+  
double ImpactToColor (string impact)
   {
	if (impact == "High") return (High_Impact_News_Color);
	else {if (impact == "Medium") return (Medium_Impact_News_Color);
	else {if (impact == "Low") return (Low_Impact_News_Color);
	else {if (impact == "Holiday") return (Bank_Holiday_Color); 
	else {return (Remarks_Color);} }}}  
   }

//+-----------------------------------------------------------------------------------------------+
//| Indicator Subroutine For Date/Time                                                            |
//+-----------------------------------------------------------------------------------------------+ 
string MakeDateTime(string strDate, string strTime)
   {
	//Print("Converting Forex Factory Time into Metatrader time..."); //added by MN
	//Converts forexfactory time & date into yyyy.mm.dd hh:mm
	int n1stDash = StringFind(strDate, "-");
	int n2ndDash = StringFind(strDate, "-", n1stDash+1);

	string strMonth = StringSubstr(strDate, 0, 2);
	string strDay = StringSubstr(strDate, 3, 2);
	string strYear = StringSubstr(strDate, 6, 4); 
   //strYear = "20" + strYear;
	
	int nTimeColonPos = StringFind(strTime, ":");
	string strHour = StringSubstr(strTime, 0, nTimeColonPos);
	string strMinute = StringSubstr(strTime, nTimeColonPos+1, 2);
	string strAM_PM = StringSubstr(strTime, StringLen(strTime)-2);

	int nHour24 = StrToInteger(strHour);
	if (strAM_PM == "pm" || strAM_PM == "PM" && nHour24 != 12) {nHour24 += 12;}
	if (strAM_PM == "am" || strAM_PM == "AM" && nHour24 == 12) {nHour24 = 0;}
 	string strHourPad = "";
	if (nHour24 < 10) strHourPad = "0";

	return(StringConcatenate(strYear, ".", strMonth, ".", strDay, " ", strHourPad, nHour24, ":", strMinute));
   }

//=================================================================================================
//===============================   Begin Imported Functions   ====================================
//=================================================================================================
// Main Webscraping function
// ~~~~~~~~~~~~~~~~~~~~~~~~~
// bool GrabWeb(string strUrl, string& strWebPage)
// returns the text of any webpage. Returns false on timeout or other error
// 
// Parsing functions
// ~~~~~~~~~~~~~~~~~
// string GetData(string strWebPage, int nStart, string strLeftTag, string strRightTag, int& nPos)
// obtains the text between two tags found after nStart, and sets nPos to the end of the second tag
//
// void Goto(string strWebPage, int nStart, string strTag, int& nPos)
// Sets nPos to the end of the first tag found after nStart 

bool bWinInetDebug = false;
int  hSession_IEType;
int  hSession_Direct;
int  Internet_Open_Type_Preconfig = 0;
int  Internet_Open_Type_Direct = 1;
int  Internet_Open_Type_Proxy = 3;
int  Buffer_LEN = 80;

#import "wininet.dll"
//Forces the request to be resolved by the origin server, even if a cached copy exists on the proxy.
#define INTERNET_FLAG_PRAGMA_NOCACHE    0x00000100 

//Does not add the returned entity to the cache. 
#define INTERNET_FLAG_NO_CACHE_WRITE    0x04000000 
 
//Forces a download of the requested file, object, or directory listing from the origin server, not from the cache.
#define INTERNET_FLAG_RELOAD            0x80000000 

int InternetOpenA(
	string 	sAgent,
	int		lAccessType,
	string 	sProxyName="",
	string 	sProxyBypass="",
	int 	lFlags=0);

int InternetOpenUrlA(
	int 	hInternetSession,
	string 	sUrl, 
	string 	sHeaders="",
	int 	lHeadersLength=0,
	int 	lFlags=0,
	int 	lContext=0);

int InternetReadFile(
	int 	hFile,
	string 	sBuffer,
	int 	lNumBytesToRead,
	int& 	lNumberOfBytesRead[]);

int InternetCloseHandle(
	int 	hInet);
	
#import

//-------------------------------------------------------------------------------------------------
int hSession(bool Direct)
   {
	string InternetAgent;
	if (hSession_IEType == 0)
	   {
		InternetAgent = "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; Q312461)";
		hSession_IEType = InternetOpenA(InternetAgent, Internet_Open_Type_Preconfig, "0", "0", 0);
		hSession_Direct = InternetOpenA(InternetAgent, Internet_Open_Type_Direct, "0", "0", 0);
	   }
	if (Direct) {return(hSession_Direct);}
	else {return(hSession_IEType);}
   }

//-------------------------------------------------------------------------------------------------
bool GrabWeb(string strUrl, string& strWebPage)
   {
	int   	hInternet;
	int		iResult;
	int   	lReturn[]	= {1};
	string 	sBuffer		= "                                                                                                                                                                                                                                                               ";	// 255 spaces
	int   	bytes;
	
	hInternet = InternetOpenUrlA(hSession(FALSE), strUrl, "0", 0, 
								INTERNET_FLAG_NO_CACHE_WRITE | 
								INTERNET_FLAG_PRAGMA_NOCACHE | 
								INTERNET_FLAG_RELOAD, 0);
								   
	if (hInternet == 0) return(false);
	Print("Reading URL: " + strUrl);	   //added by MN	
	iResult = InternetReadFile(hInternet, sBuffer, Buffer_LEN, lReturn);
	if (iResult == 0)  return(false);
	bytes = lReturn[0];
	strWebPage = StringSubstr(sBuffer, 0, lReturn[0]);
	
	//If there's more data then keep reading it into the buffer
	while (lReturn[0] != 0)
	   {
		iResult = InternetReadFile(hInternet, sBuffer, Buffer_LEN, lReturn);
		if (lReturn[0]==0) break;
		bytes = bytes + lReturn[0];
		strWebPage = strWebPage + StringSubstr(sBuffer, 0, lReturn[0]);
   	}
	Print("Closing URL web connection");   //added by MN
	iResult = InternetCloseHandle(hInternet);
	if (iResult == 0) return(false);		
	return(true);
   }

//===================================   Timezone Functions   ======================================
#import "kernel32.dll"
int  GetTimeZoneInformation(int& TZInfoArray[]);
#import
#define TIME_ZONE_ID_UNKNOWN   0
#define TIME_ZONE_ID_STANDARD  1
#define TIME_ZONE_ID_DAYLIGHT  2
int TZInfoArray[43];	
datetime TimeGMT() 
   {
	int DST = GetTimeZoneInformation(TZInfoArray);
	if (DST == 1) DST = 3600;
	else DST = 0;
	return( TimeLocal() + DST + (Offset_Hours * 3600) + (TZInfoArray[0] + TZInfoArray[42]) * 60 );
   }

//=================================================================================================
//=================================   End Imported Functions  =====================================
//=================================================================================================

//+-----------------------------------------------------------------------------------------------+
//| Indicator End                                                                                 |                                                        
//+-----------------------------------------------------------------------------------------------+