//https://msdn.microsoft.com/en-us/library/aew9yb99(v=vs.85).aspx

var debug=0;
var fso = new ActiveXObject("Scripting.FileSystemObject");
var fLog;

if(debug==1)
     fLog = fso.createtextfile("log.txt",true);
var filters=['cxx','c','cpp','h'];
var comment=
"/****************************************************************\r\n"+
"This is a simple tools for add block comments to c/cpp file's  header \r\n"+
"Copy this js file to special directory which you want to add header comments.\r\n"+
"double click and run it, It will recursive to add head copyright info to your c/cpp files \r\n\r\n\r\n"+
"It's a part of StrollingWolf Comments Remove tools. \r\n"+
"If you have any advice, please email to me: yaolixing01@gmail.com\r\n"+
"Enjoy it!\r\n"+
"					                                      ------2019 \r\n"+
"*****************************************************************/\r\n";

var ForReading = 1, ForWriting = 2, ForAppending = 8;
var asDefault = -2, asUnicode = -1, asASCII = 0;

function doWithFile(fl) 
{
    fl = fl + '';
    //search file's header, If have exist block comments, then remove it, otherwise  add our copyright header.
    var s='';
    var ext="", extPos = fl.lastIndexOf('.');
    if (extPos!=-1) 
    {
       ext = fl.substr(extPos+1).toLowerCase();
    }
    //file's extend name filter
    var i=0;
    for( i=0;i<filters.length; i++)
    {
        if (filters[i] == ext) 
        {
          break;
        }
    }
    if (i==filters.length && filters.length !=0) 
    {
        return;
    }
    
    //ForReading 1 , file is readonly. 
    //ForWriting 2, means file is write only.  
    //ForAppending 8 , means open file and appent from file end. 
	var f = fso.OpenTextFile(fl, ForReading , false, asDefault);
    if (!f) 
    {
        return;
    }
    
   //judge whether a document begins with a comment 
   var bStartWithCommentLine = 0, bStartWithCommentBlock=0;
   var sline='';
   //use state machine. skip all header comments. 
   var sFirstLineSrc ="";
   var nState = 0;
   var nLineNum=0;
   while (!f.AtEndOfStream)
   {
       sline = f.ReadLine(); 
       nLineNum++;

       if (/\S+/gi.test(sline))
       {
           if ( (nState&2)==0 && /^\s*\/\//gi.test(sline)) 
           {
              bStartWithCommentLine  = 1;
              nState |= 1;//it's line comment.
			  if(debug==1){
			       fLog.WriteLine('line comment:'+sline +' state:'+nState + " line number:"+nLineNum); 
			  }
           }else if (/^\s*\/\*/gi.test(sline)) 
           {
              bStartWithCommentBlock = 1;
              nState |= 2;//block comment start 
			  if(debug==1){
			      fLog.WriteLine('block comment start:'+sline +' state:'+nState+ " line number:"+nLineNum); 
			  }
			  if(/\*\//gi.test(sline)){
				  //single line comment 
				  nState &= ~2;//remove block comment state 
				  if(debug==1){
					  fLog.WriteLine('block comment end:'+sline+' state:'+nState + "line number:"+nLineNum); 
				  }
			  }
           }else if( (nState&2)!=0 && /\*\//gi.test(sline))
           {
              nState |= 4;//block comment end
			  nState &= ~2;//remove block comment state 
			  if(debug==1){
			      fLog.WriteLine('block comment end:'+sline+' state:'+nState + " line number:"+nLineNum); 
			  }
           }else if ((nState&2)==0  &&/\S+/gi.test(sline)) 
           {
              sFirstLineSrc = sline;
			  nState=0;
           }

           if (sFirstLineSrc.length>0) 
           {
              break;
           }
       }
   }

	if(debug==1)
	{
	   if ( bStartWithCommentLine==1) 
	   {
		   fLog.WriteLine(sline); 
	   }else if (bStartWithCommentBlock==1) 
	   {
		   fLog.WriteLine(sline); 
	   }
	}

   //write data to another temp new file 
   var fl2 = fl+'._slfsfsafsfxx0_';
   var ftmp = fso.OpenTextFile(fl2, 2, true);
   ftmp.WriteLine(comment);
   if (sFirstLineSrc.length>0) 
   {
       ftmp.WriteLine(sFirstLineSrc);
   }

   //copy left contents of origin file. 
   while (!f.AtEndOfStream)
   {
       sline = f.ReadLine(); 
       ftmp.WriteLine(sline);
   }

    ftmp.Close();
    f.Close();
    
    //del origin file
    fso.DeleteFile(fl, true);
    
    //rename temp file to origin file. 
    fso.MoveFile(fl2, fl);

}
var WSShell = WScript.CreateObject("WScript.Shell");
function getPathFiles(spath)
{
    var fd = fso.GetFolder(spath);
    var fc = new Enumerator(fd.files);

    var folderName = fso.GetBaseName(spath);

	if(folderName.indexOf('__')==0)
	{
		//we don't dowith  files which  is  '__'  as  filename's prefix 
		if(debug==1){
		    fLog.WriteLine(spath+', '+folderName); 
		}
		return;
	} 

    for (; !fc.atEnd(); fc.moveNext())
    {
        doWithFile(fc.item()); 
    }
    fc=null;

    var childPaths = new Enumerator(fd.SubFolders);
	var subfolder;
    for (; !childPaths.atEnd(); childPaths.moveNext())
    {
		subfolder = childPaths.item();

        getPathFiles(subfolder);
    }
    childPaths=null;
}

getPathFiles('.');
if(debug==1)
    fLog.Close();
fso=null;