BeginPackage["FusionAtlas`Debugging`"]

DebugEcho;DebugPrint;DebugEvaluate;SetDebugMode;SetDebugQueueInterval;SetDebugFile;DebugPrintHeld;ToStringHeld;

Begin["`Private`"];

lastDebugStatement=SessionTime[];
queuedMessages={};
queueInterval=0.;
debugFile="";

SetDebugFile[f_]:=(debugFile=f;)

SetDebugQueueInterval[x_]:=(queueInterval=x;)

SetDebugMode[x:(True|False)]:=($debugMode=x;)

$debugMode=False;

SetAttributes[DebugEvaluate,{HoldAll}]

DebugEvaluate[x___]:=If[$debugMode,Evaluate[x]]

DebugPrint[x___]:=If[$debugMode,
If[debugFile==="",
If[queueInterval==0,
Print[debugPrefix[],x];,
appendToQueue[x];
If[SessionTime[]-lastDebugStatement>queueInterval,Print@@queuedMessages;lastDebugStatement=SessionTime[];queuedMessages={}];
],
WriteString[debugFile,debugPrefix[],x,"\n"];
]
]

appendToQueue[x___]:=queuedMessages=queuedMessages~Join~If[Length[queuedMessages]>0,{"\n"},{}]~Join~{debugPrefix[]}~Join~{x}

(*appendToQueue[x___]:=queuedMessages=queuedMessages<>If[StringLength[queuedMessages]>0,"\n",""]<>(debugPrefix[]<>StringJoin@@(#/.{S_String:>S,S_:>ToString[S,InputForm]}&/@{x}));*)

debugPrefix[]:="mem: "<>ToString[MemoryInUse[]]<>" time: "<>DateString[{"Year","Month","Day"," ","Hour",":","Minute",":","Second"}]<>" "

SetAttributes[ToStringHeld,HoldFirst]

ToStringHeld[e_]:=ToString[HoldForm[e],StandardForm]

SetAttributes[DebugPrintHeld,{HoldAll}]

DebugPrintHeld[x___]:=If[$debugMode,DebugPrint[ReleaseHold[ToStringHeld/@Hold[x]]]]

SetAttributes[DebugEcho,{HoldAll}]

DebugEcho[x_]:=Module[{r},r=x;DebugPrint[r];r]

End[];

EndPackage[];