#include "htime.h"
#include "hades.h"
#include "hevent.h"
#include "heventheader.h"
#include "TRegexp.h"
#include "TSystem.h"
#include <cstdio>
ClassImp(HTime)
HTime::HTime(){;}
HTime::~HTime(){;}
Bool_t HTime::isHldName(TString name,Bool_t EvtBuilder,Bool_t silent)
{
    TString file = name;
    Int_t minLength = 15;
    if(!EvtBuilder) minLength = 13;
    if(file.Length() < minLength) {
	if(!silent)printf("IsHldName() : Filename = %s is shorter than %i Characters, cannot be a correct hld name!\n",file.Data(),minLength);
        return kFALSE;
    }
    TRegexp reg ("[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]"); 
    TRegexp reg1("[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]"); 
    Ssiz_t ext;
    Ssiz_t i = 0;
    Ssiz_t out;
    if( EvtBuilder)out = file.Index(reg ,&ext,i);
    else           out = file.Index(reg1,&ext,i);
    if(out > 1 && ext == minLength-2){ 
	return kTRUE;
    } else {
	if(!silent) printf("isHldName() : Filename = %s does not match 2Char+%i digits, cannot be a correct hld name!\n",file.Data(),minLength-2);
	return kFALSE;
    }
}
TString HTime::stripFileName(TString name,Bool_t removeEvtBuilder, Bool_t silent)
{
    
    
    
    
    
    TString file = gSystem->BaseName(name);
    TRegexp reg("[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]"); 
    Ssiz_t ext;
    Ssiz_t i = 0;
    Ssiz_t out = file.Index(reg,&ext,i);
    if(out > 1 && ext == 13){ 
       file.Replace(0 ,out - 2,"");        
       if(file.Length() < 15) {
	   if(!silent)printf("stripFileName() : Filename = %s is shorter than 15 Characters, cannot be a correct hld name!\n",file.Data());
	   file = "";
       } else { 
	   file.Replace(15,file.Length() - 15,"");
           if(removeEvtBuilder)  file.Remove(file.Length()-2,2);
       }
    } else {
	if(!silent)printf("stripFileName() : Filename = %s does not match 2Char+13 digits, cannot be a correct hld name!\n",file.Data());
        file = "";
    }
    return file;
}
void HTime::dayOfYearToDate(Int_t year,Int_t dayOfYear,Int_t& month,Int_t& day,Bool_t print)
{
    
    
    if(year < 2000) year+=2000;
    month    =0;
    day      =0;
    struct tm begin;
    time_t time_of_day;
    begin.tm_year  = year-1900;   
    begin.tm_mon   = 0;           
    begin.tm_mday  = 1;           
    begin.tm_hour  = 0;
    begin.tm_min   = 0;
    begin.tm_sec   = 0;
    begin.tm_isdst = -1;          
    time_of_day = mktime(&begin);
    time_of_day += (dayOfYear-1)*24*60*60;
    tm* filetime = gmtime(&time_of_day);
    month=filetime->tm_mon+1;
    day  =filetime->tm_mday+1;
    if(print){ printf("dayOfYearToDate : y = %04i, day of y = %3i ===> month = %02i, day = %02i \n",year,dayOfYear,month,day); }
}
void HTime::splitFileName(TString name,TString& type,Int_t& year,Int_t& dayOfYear,Int_t& hour,Int_t& minute,Int_t& second,Int_t& evtbuild,Bool_t print)
{
    
    
    
    
    
    
    Char_t t[5];
    sscanf(name.Data(),"%2s%2d%3d%2d%2d%2d%2d",t,&year,&dayOfYear,&hour,&minute,&second,&evtbuild);
    type = t;
    if(print) {
	printf("splitFileName : file = %s , type %s, y = %02i, day of y = %03i, time %02i:%02i:%02i, evtbuild %2i \n"
	       ,name.Data(),type.Data(),year,dayOfYear,hour,minute,second,evtbuild );
    }
}
TString HTime::getTypeFileName(TString name,Bool_t print)
{
    
    Int_t year,dayOfYear,hour,minute,second,evtbuild;
    TString type;
    Char_t t[5];
    sscanf(name.Data(),"%2s%2d%3d%2d%2d%2d%2d",t,&year,&dayOfYear,&hour,&minute,&second,&evtbuild);
    type = t;
    if(print) {
	printf("splitFileName : file = %s , type = %s \n",name.Data(),type.Data());
    }
    return type;
}
Int_t HTime::getYearFileName(TString name,Bool_t print)
{
    
    TString type;
    Int_t year,dayOfYear,hour,minute,second,evtbuild;
    Char_t t[5];
    sscanf(name.Data(),"%2s%2d%3d%2d%2d%2d%2d",t,&year,&dayOfYear,&hour,&minute,&second,&evtbuild);
    type = t;
    if(print) {
	printf("splitFileName : file = %s , y = %04i \n",name.Data(),year);
    }
    return year;
}
Int_t HTime::getDayFileName(TString name,Bool_t print)
{
    
    TString type;
    Int_t year,dayOfYear,hour,minute,second,evtbuild;
    Char_t t[5];
    sscanf(name.Data(),"%2s%2d%3d%2d%2d%2d%2d",t,&year,&dayOfYear,&hour,&minute,&second,&evtbuild);
    type = t;
    if(print) {
	printf("splitFileName : file = %s , day of y = %03i \n",name.Data(),dayOfYear);
    }
    return dayOfYear;
}
void HTime::getTimeFileName(TString name,Int_t& hour,Int_t& minute,Int_t& second,Bool_t print)
{
    
    TString type;
    Int_t year,dayOfYear,evtbuild;
    Char_t t[5];
    sscanf(name.Data(),"%2s%2d%3d%2d%2d%2d%2d",t,&year,&dayOfYear,&hour,&minute,&second,&evtbuild);
    type = t;
    if(print) {
	printf("splitFileName : file = %s , time %02i:%02i:%02i \n",name.Data(),hour,minute,second);
    }
}
Int_t HTime::getEvtBuilderFileName(TString name,Bool_t print)
{
    
    TString type;
    Int_t year,dayOfYear,hour,minute,second,evtbuild;
    Char_t t[5];
    sscanf(name.Data(),"%2s%2d%3d%2d%2d%2d%2d",t,&year,&dayOfYear,&hour,&minute,&second,&evtbuild);
    type = t;
    if(print) {
	printf("splitFileName : file = %s , evtbuild %02i\n",name.Data(),evtbuild);
    }
    return evtbuild;
}
time_t HTime::fileNameToTime(TString name, Bool_t print)
{
    
    
    
    
    
    
    
    
    TString type;
    Int_t y,doy,h,min,sec,evbuild;
    splitFileName(name,type,y,doy,h,min,sec,evbuild);
    Int_t month,day;
    dayOfYearToDate(y+2000,doy,month,day);
    struct tm t;
    time_t time_of_day;
    time_t gtime_of_day;
    t.tm_year  = y+100;   
    t.tm_mon   = month-1; 
    t.tm_mday  = day;     
    t.tm_hour  = h;       
    t.tm_min   = min;     
    t.tm_sec   = sec;     
    t.tm_isdst = 0;       
                          
    time_of_day = mktime(&t);           
    gtime_of_day = time_of_day - 3600;  
    struct tm* t2 = gmtime(>ime_of_day);  
    if(t2->tm_hour+2 == h) { 
	t.tm_year  = y+100;   
	t.tm_mon   = month-1; 
	t.tm_mday  = day;     
	t.tm_hour  = h;       
	t.tm_min   = min;     
	t.tm_sec   = sec;     
	t.tm_isdst = 1;
	time_of_day = mktime(&t);
    }
    if(print) { cout<<"fileNameToTime : time = "<<time_of_day<<" , "<<flush; printf("%s\n",ctime(&time_of_day)); }
    return time_of_day;
}
Int_t HTime::isDST(TString name)
{
    
    
    
    TString type;
    Int_t y,doy,h,min,sec,evbuild;
    splitFileName(name,type,y,doy,h,min,sec,evbuild);
    Int_t month,day;
    dayOfYearToDate(y+2000,doy,month,day);
    struct tm t;
    time_t time_of_day;
    time_t gtime_of_day;
    Int_t isDST = 0;
    t.tm_year  = y+100;   
    t.tm_mon   = month-1; 
    t.tm_mday  = day;     
    t.tm_hour  = h;       
    t.tm_min   = min;     
    t.tm_sec   = sec;     
    t.tm_isdst = 0;       
                          
    time_of_day = mktime(&t);           
    gtime_of_day = time_of_day - 3600;  
    struct tm* t2 = gmtime(>ime_of_day);  
    if(t2->tm_hour+2 == h) { 
	t.tm_year  = y+100;   
	t.tm_mon   = month-1; 
	t.tm_mday  = day;     
	t.tm_hour  = h;       
	t.tm_min   = min;     
	t.tm_sec   = sec;     
	t.tm_isdst = 1;
	time_of_day = mktime(&t);
        isDST = 1;
    }
    return isDST;
}
time_t HTime::runIdToTime(time_t runid, Int_t timezone, Bool_t print)
{
    
    
    
    
    
    
    
    
    
    
    
    time_t t = runid;
    t += 1200000000;
    Int_t diff = 1 - timezone;
    t -= 3600 * diff;
    if(print) { cout<<"runIdToTime : runID "<<runid<<" , timezone ="<<timezone<<" , time = "<<t<<" , "<<flush; printf("%s\n",ctime(&t)); }
    return t;
}
void HTime::runIdToBrokenTime(Int_t runid,
			      Int_t& year,Int_t& month,Int_t& day,
			      Int_t& hour,Int_t& min  ,Int_t& sec,
			      Int_t timezone,Bool_t print)
{
    
    
    
    
    
    
    
    
    
    
    
    
    time_t t = HTime::runIdToTime(runid,timezone,kFALSE);
    struct tm* t2 = gmtime(&t);
    year =  t2->tm_year     + 1900;   
    month=  t2->tm_mon      + 1;      
    day  =  t2->tm_mday;              
    hour =  t2->tm_hour + timezone;   
    min  =  t2->tm_min;               
    sec  =  t2->tm_sec;               
    if(print) {
	cout<<"runIdToBrokenTime : runID "<<runid<<" , timezone ="<<timezone
	    <<flush;
	printf(", %02i.%02i.%i, %02i:%02i:%02i\n",day,month,year,hour,min,sec);
    }
}
time_t HTime::getTimeFromEvtHeader(Bool_t print)
{
    
    
    
    
    
    
    time_t eventTime = 0;
    if(gHades && gHades->getCurrentEvent()){
	HEventHeader* evtHeader = gHades->getCurrentEvent()->getHeader();
	UInt_t evtHeaderTime = evtHeader->getTime();
	UInt_t evtHeaderDate = evtHeader->getDate();
	Int_t year = ((evtHeaderDate>>16) & 0xFF);
	Int_t month= ((evtHeaderDate>>8) & 0xFF);
	Int_t day  = (evtHeaderDate & 0xFF);
	Int_t hour = ((evtHeaderTime>>16) & 0xFF);
	Int_t min  = ((evtHeaderTime>>8) & 0xFF);
	Int_t sec  = (evtHeaderTime & 0xFF);
	struct tm t;
	time_t gtime;
	t.tm_year  = year;    
	t.tm_mon   = month;   
	t.tm_mday  = day;     
	t.tm_hour  = hour;    
	t.tm_min   = min;     
	t.tm_sec   = sec;     
	t.tm_isdst = 0;       
                              
	eventTime = mktime(&t);           
	gtime = eventTime;
	struct tm* t2 = gmtime(>ime);  
	if(t2->tm_hour+2 == hour) { 
	    t.tm_year  = year;   
	    t.tm_mon   = month;  
	    t.tm_mday  = day;    
	    t.tm_hour  = hour;   
	    t.tm_min   = min;    
	    t.tm_sec   = sec;    
	    t.tm_isdst = 1;
	    eventTime = mktime(&t);
	}
    }
    if(print) { cout<<"timeFromEventHeader : time = "<<eventTime<<" , "<<flush; printf("%s\n",ctime(&eventTime)); }
    return eventTime;
}