/*******************************************************************************************
CREATION: SiteSSJS.asp
CREATOR: George Hernandez
CREATED: 200701101937
NOTES:      
    SiteSSJS.asp contains server side JavaScript.
    SiteSSJS.asp should be included on the first line of every ASP page in this site via something like this:
        #INCLUDE VIRTUAL = "/ic/includes/ssJS.asp"
TOC:
    Site wide
    Database Functions
        gCloseConnection()
        gOpenConnection()
        gRowCount(sql)
    DateTime Functions
        gFormatDtm(dtm,Format)
    String Functions
        gSTRtoSQL(str)
        gSQLtoSQL(str)
        gRSTtoHTML(str)
        gPad(ID,intPlaces)
        String.prototype.trim = function()
        gRepeat(str, cnt)
        gHTMLEncode(str)
    Miscellany
        gDisplayJots(sql)
        gDisplayNotsTOC(sql)
        gDisplayNots(sql)
        gMakeRSS(sql,Title,Description)
        gGetKidsTop(intTabz, ParentID)
        gGetKidsBot(intTabz, ParentID)
        gGetPage(intTabz, PageID)
        gSendEmail(strFrom, strTo, strCc, strBcc, strSubject, blnIsHtml, strBody)
MOD LOG:
    2007-07-16 22:35:30
        Added gRepeat(str, cnt)
        Added gGetKidsTop(intTabz, ParentID)
        Added gGetKidsBot(intTabz, ParentID)

    200707171530 Added gGetPage(intTabz, PageID)
    200707171642 Added gSendEmail(strFrom, strTo, strCc, strBcc, strSubject, blnIsHtml, strBody)
    200707191724 Changed gDisplayNots() and gDisplayNotsTOC() so that the TOC link & anchor have the "t" in the time stamp in order to get rid of the space
    200711061638 Changed gGetKidsTop(intTabz, ParentID, ListID)    
    200801012049 Changed gDisplayNots so that post output is in div instead of p.
    200803191046 Added gHTMLEncode(str). Similar to the Server.HTMLEncode of ASP
*******************************************************************************************/

/**** Site wide ****/
var gSQL, gCNN, gRST;

var gSECONDinMS = 1000; // the number of milliseconds in a second
var gMINUTEinMS = gSECONDinMS * 60;
var gHOURinMS = gMINUTEinMS * 60;
var gDAYinMS = gHOURinMS * 24;
var gWEEKinMS = gDAYinMS * 7;
var gDAYNAME = ["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"];
var gDAYNAME3 = ["Sun","Mon","Tue","Wed","Thu","Fri","Sat"];
var gMONTHNAME = ["January","February","March","April","May","June","July","August","September","October","November","December"];
var gMONTHNAME3 = ["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"];

var gNOW = new Date(); //Date at time of page load
var gYEAR = gNOW.getFullYear();
var gMONTH = gNOW.getMonth(); //0-11
var gMONTHcal = gMONTH+1;
var gMONTHcalP = gPad(gMONTHcal,2);
var gDAYOFMONTH = gNOW.getDate();
var gDAYOFWEEK = gNOW.getDay(); //0-6 for Sun-Sat
var gHOUR = gNOW.getHours();
var gMINUTE = gNOW.getMinutes();
var gSECOND = gNOW.getSeconds();
var gMILLISECOND = gNOW.getMilliseconds();
var gNOWinMS = gNOW.getTime();
var gHOURSFROMGMT = gNOW.getTimezoneOffset()/60;
var gTZDHour = gNOW.getTimezoneOffset()/60;
var gTZDMinute = gNOW.getTimezoneOffset()%60;
var gVALUEOFtheNOW = gNOW.valueOf();
var gSEEDoftheNOW = gNOW.getTime() % 0xfffffff;
var gNOWZ = new Date(gNOW.getUTCFullYear(),gNOW.getUTCMonth(),gNOW.getUTCDate(),gNOW.getUTCHours(),gNOW.getUTCMinutes(),gNOW.getUTCSeconds());


/**** Database Functions ****/
function gCloseConnection() {
    //if (typeof(gRST)=="object") {
    //  if (gRST.State == 1) gRST.Close();
    //  //gRST = null;
    //}
    gCNN.Close();
    gCNN = null;
}
function gOpenConnection() {
    var strConnection="[Not for public viewing]"
    gCNN = Server.CreateObject("ADODB.Connection");
    gCNN.Open(strConnection)
}
//Given sql, return row count
function gRowCount(sql){
    var intRowCount=0;
    //sql="select * from Post where PostIsJot<>1 order by PostForDate desc limit 5;";
    var rst=Server.CreateObject("ADODB.Recordset");
    rst.Open(sql, gCNN);
    if (rst.EOF){
        rst.Close();
        //ErrorMessage="<p>Sorry, but nothing matched your request.</p>";
    } else {
        do {
            intRowCount++;
            rst.MoveNext();
        } while (!rst.EOF)
        rst.Close();
    }
    return intRowCount;
}

/**** DateTime Functions ****/
function gFormatDtm(dtmInput,Format) {
    var strDate = "";
    if (dtmInput=="Now") {
        var jsdate = new Date();
        //Be mindful of the server's timezone
    } else {
        var jsdate = dtmInput;
        //dtmInput EGs: new Date("Oct 22, 1968"), new Date(), dtmX
    }
    var fullyear = jsdate.getFullYear();
    var jsmonth = jsdate.getMonth(); //0-11
    var dayofthemonth = jsdate.getDate();
    var dayoftheweek = jsdate.getDay();
    var hour = jsdate.getHours();
    var minute = jsdate.getMinutes();
    var second = jsdate.getSeconds();
    var milliseconds = jsdate.getMilliseconds();
    var dtminms = jsdate.getTime();
    var valueofthedtm = jsdate.valueOf();
    switch (Format) {
    case "MMMM D, YYYY":
        strDate = gMONTHNAME[jsmonth]+" "+dayofthemonth+", "+fullyear; break;
    case "MM/DD/YYYY":
        strDate = gPad(jsmonth+1,2)+"/"+gPad(dayofthemonth,2)+"/"+fullyear; break;
    case "YYYY-MM-DD":
        strDate = fullyear+"-"+gPad(jsmonth+1,2)+"-"+gPad(dayofthemonth,2); break;
    case "YYYY-MM":
        strDate = fullyear+"-"+gPad(jsmonth+1,2); break;
    case "YYYY":
        strDate = fullyear; break;
    case "hh:mm:ss":
        strDate = gPad(hour,2)+":"+gPad(minute,2)+":"+gPad(second,2); break;
    case "hh:mm":
        strDate = gPad(hour,2)+":"+gPad(minute,2); break;
    case "LocaleString":   //Usual EG: Tuesday, June 10, 2003 08:25:22 PM
        strDate = jsdate.toLocaleString(); break;
    case "DDDD, DD MMMM YYYY hh:mm:ss": //RFC 822
        strDate = gDAYNAME[dayoftheweek]+", "+gPad(dayofthemonth,2)+" "+gMONTHNAME[jsmonth]+" "+fullyear+" "+gPad(hour,2)+":"+gPad(minute,2)+":"+gPad(second,2); break;
    case "DDD, DD MMM YYYY hh:mm:ss": //RFC 822
        strDate = gDAYNAME3[dayoftheweek]+", "+gPad(dayofthemonth,2)+" "+gMONTHNAME3[jsmonth]+" "+fullyear+" "+gPad(hour,2)+":"+gPad(minute,2)+":"+gPad(second,2); break;
    case "DD MMM YYYY hh:mm:ss": //RFC 822
        strDate = gPad(dayofthemonth,2)+" "+gMONTHNAME3[jsmonth]+" "+dayofthemonth+" "+gPad(hour,2)+":"+gPad(minute,2)+":"+gPad(second,2); break;
    case "YYYY-MM-DDthh:mm:ss": //ISO 8601
        strDate = fullyear+"-"+gPad(jsmonth+1,2)+"-"+gPad(dayofthemonth,2)+"t"+gPad(hour,2)+":"+gPad(minute,2)+":"+gPad(second,2); break;
    case "YYYY-MM-DD hh:mm:ss": //ISO 8601
        strDate = fullyear+"-"+gPad(jsmonth+1,2)+"-"+gPad(dayofthemonth,2)+" "+gPad(hour,2)+":"+gPad(minute,2)+":"+gPad(second,2); break;
    case "YYYYMMDD hhmmss": //ISO 8601
        strDate = fullyear+""+gPad(jsmonth+1,2)+""+gPad(dayofthemonth,2)+" "+gPad(hour,2)+""+gPad(minute,2)+""+gPad(second,2); break;
    case "YYYYMMDDhhmmss": //ISO 8601
        strDate = fullyear+""+gPad(jsmonth+1,2)+""+gPad(dayofthemonth,2)+""+gPad(hour,2)+""+gPad(minute,2)+""+gPad(second,2); break;
    }
    return strDate;
}

/**** String Functions ****/
//Encode a string for storing in a field in SQL
function gSTRtoSQL(str) {
    var str1 = new String(str);
    str1=str1.replace(/'/g, "''");
    return str1.trim();
}
//Take a field from SQL and puts it back
function gSQLtoSQL(str) {
    if (str=="") return "'\'";
    else {
        var str1 = new String(str);
        str=str1.replace(/'/g, "''");
        if (str.toLowerCase().trim()=="null") return "NULL";
        else return "'"+str.trim()+"'";
    }
}
//Outputting good HTML from ADO rst into HTML
function gRSTtoHTML(str) {
    str=String(str);
    if (str=="undefined" || str=="null") str = "";
    return str;
}
//Pad ID (str or int) with zeros on its left.
function gPad(ID,intPlaces) {
    //assumes that places >= length
    var str = String(ID);
    var intLength = str.length;
    var intDifference = intPlaces-intLength;
    while (intDifference>0) {
        str = "0"+str;
        intDifference--;
    }
    return str;
}
//Add trim() to String object
String.prototype.trim = function() {
    return this.replace(/^\s*(\b.*\b|)\s*$/, "$1");
}
//Return str * cnt
function gRepeat(str, cnt) { 
    return (new Array(cnt + 1)).join(str);
}
//Encode HTML so it displays instead of runs
function gHTMLEncode(str) {
    var strEncoded=String(str);
    strEncoded=strEncoded.replace(/&/,"&amp;");
    strEncoded=strEncoded.replace(/</,"&lt;");
    strEncoded=strEncoded.replace(/>/,"&gt;");
    //Server.HTMLEncode does above plus " but not ' or \
    strEncoded=strEncoded.replace(/\\/g,"&#92;"); //So escapes are not done as real escapes in MySQL
    return strEncoded;
}


/**** Miscellany ****/
function gDisplayJots(sql) {
    //sql = 
    //    "select * from Post where PostIsJot=1 "+
    //    "and PostID in (select distinct TagOnID from Tag where TagValue in('Videos')) "+
    //    "and PostID not in (select distinct TagOnID from Tag where TagValue in('Martial')) "+
    //    "order by PostForDate desc limit 5;"
    var rst=Server.CreateObject("ADODB.Recordset");
    rst.Open(sql, gCNN);
    if (rst.EOF){
        rst.Close();
        //ErrorMessage="<p>Sorry, but nothing matched your request.</p>";
    } else {
        Response.Write("<table class=\"sortable data\">\r\n");
        Response.Write("    <thead>\r\n");
        Response.Write("        <tr>\r\n");
        Response.Write("            <th>Date</th><th>Text</th><th>Link</th><th>Size</th><th>Source</th><th>Tags</th><th>R</th><th>Note</th>\r\n");
        Response.Write("        </tr>\r\n");
        Response.Write("    </thead>\r\n");
        Response.Write("    <tbody>\r\n");
        do {
            var PostID=gRSTtoHTML(rst("PostID"));
            var dtmPosted=new Date(rst("PostForDate"));
            var strPosted=gFormatDtm(dtmPosted,"YYYYMMDD hhmmss");
            var PostText=gRSTtoHTML(rst("PostText"));
            var PostLink=gRSTtoHTML(rst("PostLink"));
            var PostSize=gRSTtoHTML(rst("PostSize"));
            //var PostImage=gRSTtoHTML(rst("PostImage"));
            var PostSource=gRSTtoHTML(rst("PostSource"));
            var PostRating=gRSTtoHTML(rst("PostRating"));
            var PostValue=gRSTtoHTML(rst("PostValue"));
            Response.Write("        <tr>\r\n");    
            Response.Write("            <td><a href=\"http://www.georgehernandez.com/h/aaBlog/post.asp?PostID="+PostID+"\">"+strPosted+" Z</a></td>\r\n");    
            Response.Write("            <td>"+PostText+"</td>\r\n");
            
            if (PostLink=="") Response.Write("            <td></td>\r\n");
            else if (PostLink.length>34) Response.Write("            <td><a href=\""+PostLink+"\">"+PostLink.substr(7,12)+" &hellip; "+PostLink.substring(PostLink.length-16)+"</a></td>\r\n");
            else Response.Write("            <td><a href=\""+PostLink+"\">"+PostLink+"</a></td>\r\n");
            
            Response.Write("            <td>"+PostSize+"</td>\r\n");
            
            //if (PostImage=="") Response.Write("            <td></td>\r\n");
            //else Response.Write("            <td><img border=\"0\" src=\""+PostImage+"\" /></td>\r\n");
            
            if (PostSource=="") Response.Write("            <td></td>\r\n");
            else if (PostSource.substr(0,4)=="http") {
                if (PostSource.length>34) Response.Write("            <td><a href=\""+ PostSource+"\">"+PostSource.substr(7,12)+" &hellip; "+ PostSource.substring(PostSource.length-16)+"</a></td>\r\n");
                else Response.Write("            <td><a href=\""+PostSource+"\">"+PostSource+"</a></td>\r\n");
            } else Response.Write("            <td>"+PostSource+"</td>\r\n");
            
            Response.Write("<td>");
            var sqlTags="select TagValue from Tag where TagValue not like 'Jot:%' and TagOnID="+PostID+" order by TagValue;";
            var rstTags=Server.CreateObject("ADODB.Recordset");
            rstTags.Open(sqlTags, gCNN);
            var intTags=1;
            do {
                if (intTags!=1) Response.Write(", ");
                Response.Write(rstTags("TagValue"));
                intTags++;
                rstTags.MoveNext();
            } while (!rstTags.EOF)
            Response.Write("</td>\r\n");
            
            Response.Write("            <td>"+PostRating+"</td>\r\n");
            Response.Write("            <td>"+PostValue+"</td>\r\n");
            Response.Write("        </tr>\r\n");
            rst.MoveNext;
        } while (!rst.EOF)
        rst.Close();
        Response.Write("    </tbody>\r\n");
        Response.Write("</table>\r\n"); 
    }
}


function gDisplayNotsTOC(sql) {
    //sql="select PostID, PostForDate, PostTitle from Post where PostIsJot=0 order by PostForDate desc limit 5;";
    var rstPosts=Server.CreateObject("ADODB.Recordset");
    rstPosts.Open(sql, gCNN);
    if (rstPosts.EOF){
        rstPosts.Close();
        //ErrorMessage="<p>Sorry, but nothing matched your request.</p>";
    } else {
        Response.Write("<ol>\r\n");
        do {
            var PostID=gRSTtoHTML(rstPosts("PostID"));
            var dtmPosted=new Date(rstPosts("PostForDate"));
            var strPosted=gFormatDtm(dtmPosted,"YYYY-MM-DDthh:mm:ss");
            var PostTitle=gRSTtoHTML(rstPosts("PostTitle"));
            
            Response.Write("    <li><a href=\"#"+strPosted+"\">"+PostTitle+"</a> <span class=\"categoriesInToc\">TAGS: ");            
            var sqlTags="select TagValue from Tag where TagOnID="+PostID+" order by TagValue;"
            var rstTags=Server.CreateObject("ADODB.Recordset");
            rstTags.Open(sqlTags, gCNN);
            do{
                Response.Write(rstTags("TagValue")+". ");
                rstTags.MoveNext();
            } while(!rstTags.EOF);
            rstTags.Close();
            Response.Write("</span></li>\r\n");
            rstPosts.MoveNext();
        } while (!rstPosts.EOF)
        rstPosts.Close();
        Response.Write("</ol>\r\n");
    }
}


function gDisplayNots(sql) {
    //sql="select * from Post where PostIsJot<>1 order by PostForDate desc limit 5;";
    var rst=Server.CreateObject("ADODB.Recordset");
    rst.Open(sql, gCNN);
    if (rst.EOF){
        rst.Close();
        //ErrorMessage="<p>Sorry, but nothing matched your request.</p>";
    } else {
        do {
            var PostID=gRSTtoHTML(rst("PostID"));
            var dtmPosted=new Date(rst("PostForDate"));
            var strPosted=gFormatDtm(dtmPosted,"YYYY-MM-DDthh:mm:ss");
            var PostLink=gRSTtoHTML(rst("PostLink"));
            var PostText=gRSTtoHTML(rst("PostText"));
            var PostSource=gRSTtoHTML(rst("PostSource"));
            var PostSize=gRSTtoHTML(rst("PostSize"));
            var PostRating=gRSTtoHTML(rst("PostRating"));
            var PostTitle=gRSTtoHTML(rst("PostTitle"));
            var PostValue=gRSTtoHTML(rst("PostValue"));
            
            Response.Write("<div class=\"post\">\r\n");
            Response.Write("<a title=\"Permanent link to this post in archive\" href=\"http://www.georgehernandez.com/h/aaBlog/post.asp?PostID="+PostID+"\" name=\""+strPosted+"\">"+strPosted+ " Z</a> | TAGS: \r\n");
                
            var sqlTags="select TagValue from Tag where TagOnID="+PostID+" order by TagValue;"
            var rstTags=Server.CreateObject("ADODB.Recordset");
            rstTags.Open(sqlTags, gCNN);
            intTags=1;
            do{
                if (intTags!=1) Response.Write(", ");
                Response.Write(rstTags("TagValue"));
                intTags++;
                rstTags.MoveNext();
            } while(!rstTags.EOF);
            rstTags.Close();
            Response.Write("<br />\r\n");
            
            Response.Write("<span class=\"postTitle\">"+PostTitle+"</span>\r\n");
            Response.Write("</div>\r\n");
            
            if (!PostLink=="" || !PostSource=="" || !PostSize=="" || !PostRating==""){
            	Response.Write("<div>");
                if (!PostLink=="") Response.Write("<a href=\""+PostLink+"\">"+PostText+" <span class=\"smaller\">["+PostLink+"]</span></a>");
                if (!PostSource=="") {
                	if (PostSource.substr(0,4)=="http") Response.Write(" <span class=\"smaller\">[VIA: <a href=\""+PostSource+"\">"+PostSource+"</a>]</span>");
					else Response.Write(" <span class=\"smaller\">[VIA: "+PostSource+"]</span>");
                }
                if (!PostSize=="") Response.Write(" <span class=\"smaller\">[SIZE: "+PostSize+"]</span>");
                if (!PostRating=="") Response.Write(" <span class=\"smaller\">[RATING: "+PostRating+"]</span>");
                Response.Write("</div>\r\n");
            }
            
            Response.Write(PostValue +"\r\n\r\n");
            rst.MoveNext();
        } while (!rst.EOF)
        rst.Close();
    }
}
function gMakeRSS(sql,Title,Description){
    var rstPost=Server.CreateObject("ADODB.Recordset");
    rstPost.Open(sql, gCNN);
    if (rstPost.EOF){
        rstPost.Close();
        //ErrorMessage="<p>Sorry, but nothing matched your request.</p>";
    } else {
        Response.Write("<?xml version=\"1.0\" encoding=\"utf-8\" ?>\r\n");
        Response.Write("<rss version=\"2.0\">\r\n");
        Response.Write("<channel>\r\n");
        Response.Write("<title>"+Title+"</title>\r\n");
        Response.Write("<link>http://www.georgehernandez.com/</link>\r\n");
        Response.Write("<description>"+Description+"</description>\r\n");
        Response.Write("<language>en-us</language>\r\n");
        Response.Write("<copyright>Copyright 2007 George Hernandez</copyright>\r\n");
        Response.Write("<managingEditor>GH@georgehernandez.com (George Hernandez)</managingEditor>\r\n");
        Response.Write("<webMaster>GH@georgehernandez.com (George Hernandez)</webMaster>\r\n");
        Response.Write("<generator>text editor</generator>\r\n");
        Response.Write("<docs>http://blogs.law.harvard.edu/tech/rss</docs>\r\n");
        Response.Write("<image>\r\n");
        Response.Write("	<title>George Hernandez</title>\r\n");
        Response.Write("	<link>http://www.georgehernandez.com/</link>\r\n");
        Response.Write("	<url>http://www.georgehernandez.com/h/Media/zMisc/GHLogo.gif</url>\r\n");
        Response.Write("	<width>34</width>\r\n");
        Response.Write("	<height>60</height>\r\n");
        Response.Write("</image>\r\n");
        
        //var dtmPosted=new Date(rstPost("PostForDate"));
        //var strPosted=gFormatDtm(new Date(rstPost("PostForDate")),"DDD, DD MMM YYYY hh:mm:ss");
        Response.Write("<pubDate>"+gFormatDtm(new Date(rstPost("PostForDate")),"DDD, DD MMM YYYY hh:mm:ss")+"</pubDate>\r\n");
        Response.Write("<lastBuildDate>Mon, 01 Jan 2007 18:35:01 GMT</lastBuildDate>\r\n\r\n\r\n");
        do {
            var PostID=gRSTtoHTML(rstPost("PostID"));
            var dtmPostFor=new Date(rstPost("PostForDate"));
            var dtmPostPub=new Date(rstPost("PostPubDate"));
            var PostText=gRSTtoHTML(rstPost("PostText"));
            var PostLink=gRSTtoHTML(rstPost("PostLink"));
            var PostSize=gRSTtoHTML(rstPost("PostSize"));
            //var PostImage=gRSTtoHTML(rstPost("PostImage"));
            var PostSource=gRSTtoHTML(rstPost("PostSource"));
            var PostRating=gRSTtoHTML(rstPost("PostRating"));
            var PostIsJot=gRSTtoHTML(rstPost("PostIsJot"));
            var PostTitle=gRSTtoHTML(rstPost("PostTitle"));
            var PostValue=gRSTtoHTML(rstPost("PostValue"));
    
            Response.Write("<item>\r\n");
            Response.Write("    <pubDate>"+gFormatDtm(dtmPostPub,"DDD, DD MMM YYYY hh:mm:ss")+"</pubDate>\r\n");
            Response.Write("    <guid isPermaLink=\"true\">http://www.georgehernandez.com/h/aaBlog/post.asp?PostID="+PostID+"</guid>\r\n");
            if (PostTitle=="") Response.Write("    <title>"+gFormatDtm(dtmPostFor,"YYYY-MM-DD hh:mm:ss")+"</title>\r\n    ");
            else Response.Write("    <title>"+PostTitle+"</title>\r\n");
            
            var sqlTag="select TagValue from Tag where TagOnID="+PostID+" order by TagValue;"
            var rstTag=Server.CreateObject("ADODB.Recordset");
            rstTag.Open(sqlTag, gCNN);
            do{
                Response.Write("<category>"+rstTag("TagValue")+"</category>");
                rstTag.MoveNext();
            } while(!rstTag.EOF);
            rstTag.Close();
            Response.Write("\r\n");
            
            
            if (!PostLink=="" || PostIsJot=="1"){
                Response.Write("    <description><![CDATA[");
                Response.Write("<p><a href=\""+PostLink+"\">"+PostText+" <span class=\"smaller\">["+PostLink+"]</span></a>");
                if (!PostSource==""){
                    Response.Write(" <span class=\"smaller\">[VIA: <a href=\""+PostSource+"\">"+PostSource+"</a>]</span>");
                }
                if (!PostSize==""){
                    Response.Write(" <span class=\"smaller\">[SIZE: "+PostSize+"]</span>");
                }
                Response.Write("</p>\r\n");
                Response.Write(PostValue+"]]></description>\r\n");
            } else Response.Write("    <description><![CDATA["+PostValue+"]]></description>\r\n");
            
            Response.Write("    <description><![CDATA[");
            if (PostLink!="" || PostText!="" || PostSize!="" || PostSource!="") {
                Response.Write("<div>\r\n");
                if (PostLink!="") Response.Write("LINK: <a href=\""+PostLink+"\">"+PostLink+"</a><br />\r\n");
                if (PostText!="") Response.Write("TEXT: "+PostText+"<br />\r\n");
                if (PostSize!="") Response.Write("SIZE: "+PostSize+"<br />\r\n");
                //if (PostImage!="") Response.Write("IMAGE: <img border=\"0\" src=\""+PostImage+"><br />\r\n");
                if (PostSource!="") {
                    if (PostSource.substr(0,7)=="http://") Response.Write("SOURCE: <a href=\""+PostSource+"\">"+PostSource+"</a><br />\r\n");
                    else Response.Write("SOURCE: "+PostSource+"<br />\r\n");
                }
                if (PostRating!="") Response.Write("RATING (1-9): "+PostSize+"<br />\r\n");
                Response.Write("<br /></div>\r\n");
            }
            if (PostValue!="") Response.Write(PostValue +"\r\n");
            Response.Write("]]></description>\r\n");        
            
            Response.Write("    <author>glh@georgehernandez.com (George Hernandez)</author>\r\n");
            Response.Write("</item>\r\n");
            rstPost.MoveNext();
        } while (!rstPost.EOF)
        rstPost.Close();
        Response.Write("</channel>\r\n");
        Response.Write("</rss>\r\n");
    }
}


function gGetKidsTop(intTabz, ParentID, ListID) {
    var sqlKidsTop="select * from Page where PageParentID="+ParentID+" order by PageListOrder, PageTitle;";
    var rstKidsTop=Server.CreateObject("ADODB.Recordset");
    rstKidsTop.Open(sqlKidsTop, gCNN);
    Response.Write(gRepeat("    ",intTabz)+"<ul class=\"aqtree3\" id=\""+ListID+"\">\r\n");
    gGetPage(intTabz+1, ParentID);
    Response.Write(gRepeat("    ",intTabz+2)+"<ul>\r\n");
    gGetPage(intTabz+3, ParentID);
    Response.Write(gRepeat("    ", intTabz+3)+"</li>\r\n");
    while (!rstKidsTop.EOF) {
        Response.Write(gRepeat("    ",intTabz+3)+"<li><a href=\""+String(rstKidsTop("PagePath"))+String(rstKidsTop("PageName"))+"\" title=\""+String(rstKidsTop("PageDescription"))+"\">"+String(rstKidsTop("PageTitle"))+"</a>\r\n");
        gGetKidsBot(intTabz+4, Number(rstKidsTop("PageID")));
        Response.Write(gRepeat("    ",intTabz+3)+"</li>\r\n");
        rstKidsTop.MoveNext();
    }
    Response.Write(gRepeat("    ",intTabz+2)+"</ul>\r\n");
    Response.Write(gRepeat("    ", intTabz+1)+"</li>\r\n");
    Response.Write(gRepeat("    ",intTabz)+"</ul>\r\n");
}
function gGetKidsBot(intTabz, ParentID) {
    var sqlKidsBot="select * from Page where PageParentID="+ParentID+" order by PageListOrder, PageTitle;";
    //Response.Write(sqlKidsBot); Response.End(); //DEV ONLY
    var rstKidsBot=Server.CreateObject("ADODB.Recordset");
    rstKidsBot.Open(sqlKidsBot, gCNN);
    if (rstKidsBot.EOF) {
        rstKidsBot.Close();
    } else {
        Response.Write(gRepeat("    ",intTabz)+"<ul>\r\n");
        gGetPage(intTabz+1, ParentID);
        Response.Write(gRepeat("    ", intTabz+1)+"</li>\r\n");
        while (!rstKidsBot.EOF) {
            Response.Write(gRepeat("    ",intTabz+1)+"<li><a href=\""+String(rstKidsBot("PagePath"))+String(rstKidsBot("PageName"))+"\" title=\""+String(rstKidsBot("PageDescription"))+"\">"+String(rstKidsBot("PageTitle"))+"</a>\r\n");
            gGetKidsBot(intTabz+2, Number(rstKidsBot("PageID")));
            Response.Write(gRepeat("    ",intTabz+1)+"</li>\r\n");
            rstKidsBot.MoveNext();
        }
        Response.Write(gRepeat("    ",intTabz)+"</ul>\r\n");
        rstKidsBot.Close();
    }
}
function gGetPage(intTabz, PageID) {
    //For aqtree, the parent needs to be listed with the children too
    var sqlThisPage="select * from Page where PageID="+PageID+";";
    var rstThisPage=Server.CreateObject("ADODB.Recordset");
    rstThisPage.Open(sqlThisPage, gCNN);
    Response.Write(gRepeat("    ",intTabz)+"<li><a href=\""+String(rstThisPage("PagePath"))+String(rstThisPage("PageName"))+"\" title=\""+String(rstThisPage("PageDescription"))+"\">"+String(rstThisPage("PageTitle"))+"</a>\r\n");
    rstThisPage.Close();
}
function gSendEmail(strFrom, strTo, strCc, strBcc, strSubject, blnIsHtml, strBody) {
    //Here is a sample script using CDOSYS sending email thru a remote SMTP server:
    var objMessage=Server.CreateObject("CDO.Message") 
    objMessage.From=strFrom;
    objMessage.To=strTo;  //EG: "georgelhernandez@iclops.com;aube@iclops.com" 
    objMessage.Cc=strCc; 
    objMessage.Bcc=strBcc;
    objMessage.Subject=strSubject;
    if (blnIsHtml) {
        objMessage.HtmlBody=strBody; //EG: "<html><body><p>Hello</p></body></html>"
    } else {
        objMessage.TextBody=strBody; //EG: "world!"
    }
    objMessage.Configuration.Fields.Item("http://schemas.microsoft.com/cdo/configuration/sendusing")=2;
    objMessage.Configuration.Fields.Item("http://schemas.microsoft.com/cdo/configuration/smtpserver")="[Not for public viewing]";
    objMessage.Configuration.Fields.Item("http://schemas.microsoft.com/cdo/configuration/smtpserverport")="[Not for public viewing]";
    objMessage.Configuration.Fields.Item("http://schemas.microsoft.com/cdo/configuration/smtpconnectiontimeout")="[Not for public viewing]";
    objMessage.Configuration.Fields("http://schemas.microsoft.com/cdo/configuration/smtpauthenticate")="[Not for public viewing]";
    objMessage.Configuration.Fields("http://schemas.microsoft.com/cdo/configuration/sendusername")="[Not for public viewing]";
    objMessage.Configuration.Fields("http://schemas.microsoft.com/cdo/configuration/sendpassword")="[Not for public viewing]";
    objMessage.Configuration.Fields.Update();
    objMessage.Send();
}
