///////////////////////////////////////////////////////////////////////////////////////////////////
// File: tools.js
// Creator: Monjay Settro, Devbleue Inc.
// Purpose: library of reusable functions, prototypes String.trim()
///////////////////////////////////////////////////////////////////////////////////////////////////

function findPos(obj)
{
   if (!obj) return false;

   // courtesy of quirksmode
	var curleft = curtop = 0;
	if (obj.offsetParent) {
		curleft = obj.offsetLeft
		curtop = obj.offsetTop
		while (obj = obj.offsetParent) {
			curleft += obj.offsetLeft
			curtop += obj.offsetTop
		}
	}

   var v = new Array;
       v['top'] = curtop
       v['left'] = curleft

	return v
}

function print_array(A)
{
   var s;
   for(i in A)
   {
      s = (s) ? s + "\n" : "";
      s = s + i + " = " + A[i];
   }
   alert(s);
}

function add_dash(before, after)
{
   // if (!before && after) then should return a dash so that after value does not appear to be a before value
   if (before && after)
   {
      return ' - ';
   }
   return '';
}

function prep_calendar_data_value(o)
{
   var text = drill_for_text(o);
       text = replace_markup(text);
       text = text.trim();

   return text;
}

function replace_markup(text)
{
   var replaced;

       replaced = text.replace(/\[img\]/g, '<img class="imageInText" src="').replace(/\[\/img\]/g, '">').trim();
       replaced = replaced.replace(/\[important\]/g, '<span class="important">').replace(/\[\/important\]/g, '</span>').trim();
       replaced = replaced.replace(/\[empty\]/g, '').trim();
       replaced = replaced.replace(/\[nbsp\]/g, '&nbsp;').trim();
       replaced = replaced.replace(/\[newline\]/g, '<br />').trim();
       replaced = replaced.replace(/\[bold\]/g, '<b>').replace(/\[\/bold\]/g,'</b>').trim();
       replaced = replaced.replace(/\[underline\]/g, '<u>').replace(/\[\/underline\]/g,'</u>').trim()

       replaced = replaced.replace(/\[table\]/g, '<table class="textTable">').replace(/\[\/table\]/g, '</table>').trim();
       replaced = replaced.replace(/\[row\]/g, '<tr class="textTableRow">').replace(/\[\/row\]/g, '</tr>').trim();
       replaced = replaced.replace(/\[cell\]/g, '<td class="textTableCell" valign="top">').replace(/\[\/cell\]/g, '</td>').trim();

       replaced = replaced.replace(/\[link\]/g, '<a class="textLink" target="_blank" ').replace(/\[\/link\]/g, '</a>').trim();
       replaced = replaced.replace(/\[linkurl\]/g, 'href="').replace(/\[\/linkurl\]/g, '">').trim();
       replaced = replaced.replace(/\[linktext\]/g, '').replace(/\[\/linktext\]/g, '').trim();

       replaced = replaced.replace(/\[email\]/g, '<a class="textLink" ').replace(/\[\/email\]/g, '</a>').trim();
       replaced = replaced.replace(/\[emailaddr\]/g, 'href="mailto:').replace(/\[\/emailaddr\]/g, '').trim();
       replaced = replaced.replace(/\[emailsubject\]/g, '?subject=').replace(/\[\/emailsubject\]/g, '">').trim();
       replaced = replaced.replace(/\[emailtext\]/g, '').replace(/\[\/emailtext\]/g, '').trim();

       replaced = replaced.replace(/\[list\]/g, '<ul>').replace(/\[\/list\]/g,'</ul>').trim();
       replaced = replaced.replace(/\[steps\]/g, '<ol>').replace(/\[\/steps\]/g,'</ol>').trim();
       replaced = replaced.replace(/\[item\]/g, '<li>').replace(/\[\/item\]/g,'</li>').trim();

       replaced = replaced.replace(/\[colorblock\]([^\[]+)\[\/colorblock\]/g, function ($1){ return colorblock($1); } )
       
       replaced = replaced.replace(/'([^']+)'/g, '&#145;$1&#146;');
       replaced = replaced.replace(/"([^"]+)'/g, '&quot;');

   return replaced;
}

function colorblock(code, opacity)
{ 
   // code = [colorblock]...[/colorblock]
   // opacity is a placeholder in case it is needed later

   var color = code   
       color = color.replace('\[colorblock\]',   '')
       color = color.replace('\[\/colorblock\]', '')
       color = color.replace('&nbsp;','')
       color = color.trim()

   var html = '<span class="colorblock" style="background-color:<color>;color:<color>;">&mdash;</span>'
       html = html.replace(/<color>/g, pastel(color,opacity));

   return html
}

function drill_for_text(tag)
{
   // avoid any elements in the td tag, just take the text content...
   var text = '';
   if (tag)
   {
      for (var n = 0; n < tag.childNodes.length; n = n + 1)
      {
         if (tag.childNodes[n].length)
         {
             text = text + tag.childNodes[n].nodeValue;
         }
         else
         {
            text = text + drill_for_text(tag.childNodes[n]);
         }
      }
   }
   return text;
}

function get_calconf_xml(responseText, subcategory)
{
   var R = new Array()
       R['doc'] = false
       R['error_code'] = false
       R['error_text'] = false
       R['html'] = false

   if (subcategory)
   {
      R['html'] = extract_table_text(responseText, subcategory)
      if (!R['html'])
      {
         R['error_code'] = 1
         R['error_text'] = 'subcategory table named' + "'" + subcategory + "'" + ' not found in responseText.'
         return false
      }
   }
   else
   {
      R['html'] = responseText
   }

   if (window.ActiveXObject)
   {
      // 02/21/09, monjay, found out the hard way that Microsoft.XMLDOM no longer likes HTML Doctypes
      // 02/21/09, monjay, Microsoft has deemed DTD's insecure: http://msdn.microsoft.com/en-us/library/ms761392(VS.85).aspx
      // 02/21/09, monjay, so before loadXML(), I strip out <!DOCTYPE...> and replace &nbsp; with a space
      // 02/21/09, monjay, NOT SURE HOW compatible this change is in the long run but solves the short term problem.
      // 02/21/09, these resources were helpful to one degree or another...
      //    MSXML DOM Reference: http://msdn.microsoft.com/en-us/library/ms764730(VS.85).aspx
      //    http://msdn.microsoft.com/en-us/library/aa468547.aspx
      //    Standard DTD's that didn't work: http://www.w3.org/QA/2002/04/valid-dtd-list.html
      //    IXMLDOMParseError Members: http://msdn.microsoft.com/en-us/library/ms767720(VS.85).aspx
      //    MS MSXML Versions: http://support.microsoft.com/kb/269238
      //    http://www.satoshii.org/markup/dtd/xhtml11-msxml.en
      //    Inspecting Versions of MSXML: http://blogs.msdn.com/xmlteam/archive/2006/10/23/using-the-right-version-of-msxml-in-internet-explorer.aspx
      //    Dom Security: http://msdn.microsoft.com/en-us/library/ms761392(VS.85).aspx

      var temp = R['html']
          temp = temp.replace(/\<\!DOCTYPE[^>]*>/g, '');
          temp = temp.replace(/\&([^;]*);/g, '[$1]')

      var MicrosoftDomObjectName = 'Microsoft.XMLDOM';
          // 02/21/09, monjay, tried these variety of alternatives ProgID's but they seem to guarantee a parse error 
          //var MicrosoftDomObjectName = 'Msxml2.DOMDocument.3.0';
          //var MicrosoftDomObjectName = 'Msxml2.DOMDocument.4.0';
          //var MicrosoftDomObjectName = 'Msxml2.DOMDocument.5.0';
          //var MicrosoftDomObjectName = 'Msxml2.DOMDocument.6.0';

      R['doc'] = new ActiveXObject(MicrosoftDomObjectName)
      R['doc'].resolveExternals = false;
      R['doc'].validateOnParse = false;
      R['doc'].setProperty("ProhibitDTD", false); // if set to true, then 'Invalid at top level of document'
      R['doc'].async = false;

      var parse_ok = R['doc'].loadXML(temp)
          // 02/21/09, monjay, this line always gives parse error "Invalid syntax" for any MicrosoftDomObjectName
          //var parse_ok = R['doc'].load(temp)

      if (!parse_ok)
      {
         var msg = MicrosoftDomObjectName + ' could not parse the document. ' + R['doc'].parseError.reason
         alert(msg);
      }

      if (!R['doc'])
      {
         R['error_code'] = 2
         R['error_text'] = 'Microsoft.XMLDOM not created.'
         return false
      }
   }
   else   // Mozilla, Firefox, Opera, etc...
   {
      var parser = new DOMParser();
      R['doc'] = parser.parseFromString(R['html'], "text/xml")
      if (R['doc'])
      {
         if (drill_for_text(R['doc']).match('Error:'))
         {
            R['error_code'] = 3
            R['error_text'] = R['doc']
            return false
         }
      }
   }

   return R
}

function extract_table_text(text, subcategory)
{
   if (!text.length)
   {
      return false;
   }

   var index = new Array;
       index['end'] = text.indexOf(subcategory + ' '); //try to find text 'SubcategoryN '

   if (index['end'] > -1)
   {
      var text_part = text.substring(0, index['end']);
      
      index['i'] = 0;
      index['nearest'] = 0;
      while (index['i'] < index['end'])
      {
         index['table'] = text_part.indexOf('<table', index['i']);
         if (index['table'] > index['nearest'])
         {
            index['nearest'] = index['table']
            index['i'] = index['nearest'] + 1;
         }
         else
         {
            index['i'] = index['end'] + 1;
         }
      }
      index['nearest_end'] = text.indexOf('</table>', index['nearest']) + 8;

      return '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"'
           + '    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">'
           + '<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" dir="ltr">'
           + '<head>'
           + '<title>Calendar Data:: Derived</title>'
           + '</head>'
           + '<body>'
           + text.substring(index['nearest'], index['nearest_end'])
           + '</body>'
           + '</html>'
   }

   return false;
}
///////////////////////////////////////////////////////////////////////////////////////////////////

function getCalObj(idName)
{
   var o = document.getElementById(idName);
   if (o)
   {
      return o
   }
}

function getCalVal(idName)
{
   var o = document.getElementById(idName);
   if (o)
   {
      return o.innerHTML
   }
//alert(idName + 'didn\'t exist')
}

function setCalVal(idName, value)
{
   var o = document.getElementById(idName);
   if (o) { o.innerHTML = value; return o.innerHTML; }

   return false;
}

function setCalChecked(idName, value)
{
   var o = document.getElementById(idName);
   if (o) { o.checked = value; return o.checked; }

   return false;

}

function getCalClass(idName)
{
   var o = document.getElementById(idName);
   if (o)
   { 
      return o.className;
   }
   return false;
}

function setCalClass(idName, className)
{
   var o = document.getElementById(idName);
       if (o) { o.className = className; return o.className; }

   return false;
}

function setCalClick(idName, clickAction)
{
   // call: setCalClick('element1', function() { ... });
   
   var o = document.getElementById(idName);
       if (o) { o.onclick = clickAction; return o.onclick; }

   return false;
}
function setCalFormVal(idName, value)
{
   var o = document.getElementById(idName); // put a value in the corresponding field
       if (o) { o.value = value; return o.value; }

   return false;
}
function setCalFormCheck(idName, checked)
{
   var o = document.getElementById(idName); // put a value in the corresponding field
       if (o) { o.check = checked; return o.checked; }

   return false;
}

///////////////////////////////////////////////////////////////////////////////////////////////////

function calc_last_day_of_month(month, year)
{
   var last_day_number = 31;
       last_day_number = (month == 'April' || month == 'June' || month == 'September' || month == 'Nov' ) ? 30 : last_day_number;
       if (month == 'February')
       {
          last_day_number = 29;
          last_day_number = (year % 4 != 0)   ? 28 : last_day_number;
          last_day_number = (year % 400 == 0) ? 29 : last_day_number;
          last_day_number = (year % 100 == 0) ? 28 : last_day_number;
       }
   
   return last_day_number;
}

function weekdaynamesdates_to_string(weekday_name)
{
   weekday_name = weekday_name.replace(/[Mm][Oo][Nn][Dd][Aa][Yy][Ss]/, 'Mondays')
   weekday_name = weekday_name.replace(/[Tt][Uu][Ee][Ss][Dd][Aa][Yy][Ss]/, 'Tuesdays')
   weekday_name = weekday_name.replace(/[Ww][Ee][Dd][Nn][Ee][Ss][Dd][Aa][Yy][Ss]/, 'Wednesdays')
   weekday_name = weekday_name.replace(/[Tt][Hh][Uu][Rr][Ss][Dd][Aa][Yy][Ss]/, 'Thursdays')
   weekday_name = weekday_name.replace(/[Ff][Rr][Ii][Dd][Aa][Yy][Ss]/, 'Fridays')
   weekday_name = weekday_name.replace(/[Ss][Aa][Tt][Uu][Rr][Dd][Aa][Yy][Ss]/, 'Saturdays')
   weekday_name = weekday_name.replace(/[Ss][Uu][Nn][Dd][Aa][Yy][Ss]/, 'Sundays')

   var s = ''
   if ((calconf[weekday_name]) && (calconf[weekday_name].length > 0))
   {
      for (var i=0; i < calconf[weekday_name].length; i++)
      {
         s = s + ((!s) ? '' : ',')
         s = s + calconf[weekday_name][i];
      }
   }
   return s;
}

function is_date(v)
{
   if (v.match('[0-9]/[0-9]/[0-9][0-9][0-9][0-9]'))
   {
      return true; // M/D/YYYY
   }
   if (v.match('[0-9]/[0-9][0-9]/[0-9][0-9][0-9][0-9]'))
   {
      return true; // M/DD/YYYY
   }
   if (v.match('[0-9][0-9]/[0-9]/[0-9][0-9][0-9][0-9]'))
   {
      return true; // MM/D/YYYY
   }
   if (v.match('[0-9][0-9]/[0-9][0-9]/[0-9][0-9][0-9][0-9]'))
   {
      return true; // MM/DD/YYYY
   }
   return false;
}

function two_digits(v)
{
   if ((v.length < 2) || ((v > -1) && (v < 10)))
   {
      return '0' + v
   }
   return v;
}

///////////////////////////////////////////////////////////////////////////////////////////////////
// some prototype assistance

String.prototype.trim = function() { return this.replace(/^\s+|\s+$/g,""); }