
var allHtmlEditors = new Array();


function createHtmlEditor(id, rel, site_id, basehref, parent_id, allow_uploads, convert_tags, config_path, options)
{
  if (!basehref || basehref == '')
  {
    basehref = window.location.href;
    basehref = basehref.replace(/\/[^\/]*$/, '/');
  }

  if (!config_path || config_path == '')
  {
    config_path = "../../browser/config.js";
  }
  else if (config_path.match(/\//) == null)
  {
    // Config path is a single segment ... prefix rest of path

    config_path = "../../browser/" + config_path;
  }

  // Copy the initial content into the private textarea

  var src_textarea = document.getElementById(id);
  var dst_textarea = document.getElementById(id + '___edit');
  if (src_textarea && dst_textarea)
  {
    dst_textarea.value = fromTextToHtml(src_textarea.value, basehref, convert_tags);
  }

  // Check to see if the source text area contains a <html or <body tag. We use the presence or
  // absence of these tags to determine whether fullpage mode should be enabled.

  var fullpage = false;
  if (src_textarea.value.match(/<\s*html/i) != null || src_textarea.value.match(/<\s*body/i) != null)
  {
    fullpage = true;
  }

  var oFCKeditor = new FCKeditor(id + '___edit', dst_textarea.style.width, dst_textarea.style.height);
  oFCKeditor.BasePath = rel + '/fckeditor/';
  oFCKeditor.Config["CustomConfigurationsPath"] = config_path;
  //oFCKeditor.Config["LinkBrowserURL"] = '../../../browser/browser/default/browser.html?Connector=../../connectors/php/connector.php&SiteId=' + encodeURIComponent(site_id) + '&BaseHref=' + encodeURIComponent(basehref);
  oFCKeditor.Config["LinkBrowserURL"] = '../../../browser/browser/default/browser.html?Connector=../../connectors/php/connector.php&SiteId=' + encodeURIComponent(site_id) + '&BaseHref=' + encodeURIComponent(basehref);
  oFCKeditor.Config["LinkUploadURL"] = '../../../browser/connectors/php/upload.php?Type=Media&SiteId=' + encodeURIComponent(site_id) + '&ParentId=' + encodeURIComponent(parent_id) + '&BaseHref=' + encodeURIComponent(basehref);
  oFCKeditor.Config["ImageBrowserURL"] = '../../../browser/browser/default/browser.html?Connector=../../connectors/php/connector.php&Type=Image&SiteId=' + encodeURIComponent(site_id) + '&BaseHref=' + encodeURIComponent(basehref);
  oFCKeditor.Config["ImageUploadURL"] = '../../../browser/connectors/php/upload.php?Type=Image&SiteId=' + encodeURIComponent(site_id) + '&ParentId=' + encodeURIComponent(parent_id) + '&BaseHref=' + encodeURIComponent(basehref);
  oFCKeditor.Config["FlashBrowserURL"] = '../../../browser/browser/default/browser.html?Connector=../../connectors/php/connector.php&Type=Flash&SiteId=' + encodeURIComponent(site_id) + '&BaseHref=' + encodeURIComponent(basehref);
  oFCKeditor.Config["FlashUploadURL"] = '../../../browser/connectors/php/upload.php?Type=Flash&SiteId=' + encodeURIComponent(site_id) + '&ParentId=' + encodeURIComponent(parent_id) + '&BaseHref=' + encodeURIComponent(basehref);
  oFCKeditor.Config["BaseHref"] = basehref;
  oFCKeditor.Config["ImageUpload"] = allow_uploads;
  oFCKeditor.Config["FlashUpload"] = allow_uploads;
  oFCKeditor.Config["LinkUpload"] = allow_uploads;
  oFCKeditor.Config["FullPage"] = fullpage;
  oFCKeditor.Config["ParentId"] = parent_id;
  oFCKeditor.Config["SiteId"] = site_id;
  oFCKeditor.Config["ConvertTags"] = convert_tags;
  oFCKeditor.Config["Options"] = options;

  oFCKeditor.ReplaceTextarea(); 

  allHtmlEditors.push(id);
}


function FCKeditor_OnComplete(editorInstance)
{
  // If a custom OnComplete function is present, call that function now.

  if (typeof(Custom_OnComplete) == 'function')
  {
    Custom_OnComplete(editorInstance);
  }

  // Perform the rest of the necessary initialisation.

  var btn_name = editorInstance.Name.replace(/edit$/, 'btn_text');
  var btn = document.getElementById(btn_name);
  if (btn) btn.disabled = false;

  var btn_name = editorInstance.Name.replace(/edit$/, 'btn_html');
  var btn = document.getElementById(btn_name);
  if (btn) btn.disabled = false;

  editorInstance.Events.AttachEvent('OnAfterLinkedFieldUpdate', eventOnAfterLinkedFieldUpdate);
}


function changeParent(field)
{
  for (var i = 0; i < allHtmlEditors.length; i++)
  {
    var oFCKeditor = null;
    if (typeof(FCKeditorAPI) != 'undefined')
    {
      oFCKeditor = FCKeditorAPI.GetInstance(allHtmlEditors[i] + '___edit');
    }
    if (oFCKeditor)
    {
      if (field)
      {
        var parent_id = field.value.replace(/-\d+$/, '');
        if (parent_id == '') parent_id = -oFCKeditor.Config["SiteId"];
        oFCKeditor.Config["ImageUploadURL"] = oFCKeditor.Config["ImageUploadURL"].replace(/ParentId=[\d-]+/, 'ParentId=' + parent_id);
        oFCKeditor.Config["FlashUploadURL"] = oFCKeditor.Config["FlashUploadURL"].replace(/ParentId=[\d-]+/, 'ParentId=' + parent_id);
        oFCKeditor.Config["ParentId"] = parent_id;
      }
    }
  }
}


function toggleEditor(id)
{
  var oFCKeditor = null;
  if (typeof(FCKeditorAPI) != 'undefined')
  {
    oFCKeditor = FCKeditorAPI.GetInstance(id + '___edit');
  }

  var div_text = document.getElementById(id + '___div_text');
  var div_html = document.getElementById(id + '___div_html');

  if (div_text && div_html)
  {
    if (div_text.style.display != 'none')
    {
      // Text area is currently visible - switch to WYSIWYG

      if (oFCKeditor)
      {
	oFCKeditor.SetData(fromTextToHtml(document.getElementById(id).value, oFCKeditor.Config["BaseHref"], oFCKeditor.Config["ConvertTags"]));
      }

      div_text.style.display = 'none';
      div_html.style.display = 'block';

      // This is a hack for Gecko 1.0.x ... it stops editing when the editor is hidden.
      if (oFCKeditor && !document.all)
      {
	if (oFCKeditor.EditMode == FCK_EDITMODE_WYSIWYG)
	{
	  oFCKeditor.MakeEditable();
	}
      }
    }
    else
    {
      // WYSIWYG is currently visible - switch to text

      if (oFCKeditor)
      {
	document.getElementById(id).value = fromHtmlToText(oFCKeditor.GetXHTML(), oFCKeditor.Config["BaseHref"], oFCKeditor.Config["ConvertTags"]);
      }

      div_text.style.display = 'block';
      div_html.style.display = 'none';
    }
  }
}


function eventOnAfterLinkedFieldUpdate(editorInstance)
{
  // We're about to submit the form. If the textarea is not visible we update it's content
  // from the WYSIWYG editor.

  var id = editorInstance.Name.replace(/___edit$/, '');
  var div_text = document.getElementById(id + '___div_text');

  if (div_text && div_text.style.display == 'none')
  {
    var textarea = document.getElementById(id);
    if (textarea)
    {
      textarea.value = fromHtmlToText(editorInstance.GetXHTML(), editorInstance.Config["BaseHref"], editorInstance.Config["ConvertTags"]);
    }
  }
}


// Implement a simple state machine to parse an attribute list into an array. Take into
// account that the presence of nested inline tags can break the syntax.

function parseAttributeList(attr)
{
  var attributes = new Array;
  var state = 0;
  var pos = 0;
  var name = '';
  var attribute = '';
  var nest = 0;

  while (pos < attr.length)
  {
    var c = attr.charAt(pos);
    switch (state)
    {
      case 0:
        if (c != ' ' && c != "\t" && c != "\r" && c  != "\n")
        {
          name += c; state = 1;
        }
        break;
      case 1:
        if (c == '=')
        {
          state = 3;
        }
        else if (c == ' ' || c == "\t" || c == "\r" || c == "\n")
        {
          state = 2;
        }
        else
        {
          name += c;
        }
        break;
      case 2:
        if (c == '=')
        {
          state = 3;
        }
        break;
      case 3:
        if (c == '"')
        {
          state = 5;
        }
        else if (c != ' ' && c != "\t" && c != "\r" && c != "\n")
        {
          attribute += c;
          state = 4;
        }
        break;
      case 4:
        if (c != ' ' && c != "\t" && c != "\r" && c != "\n")
        {
          attribute += c;
        }
        else
        {
          attributes.push(new Array(name.toLowerCase(), attribute));
          name = '';
          attribute = '';
          state = 0;
        }
        break;
      case 5:
        if (c != '"')
        {
          attribute += c;
	  if (c == '{') state = 6;
	  else if (c == '}' && nest > 0) state = 7;
        }
        else
        {
	  if (nest == 0)
	  {
            attributes.push(new Array(name.toLowerCase(), attribute));
            name = '';
            attribute = '';
            state = 0;
	  }
	  else
	  {
	    attribute += c;
	  }
        }
        break;
      case 6:
	if (c != '"')
	{
	  attribute += c;
	  if (c == '{') nest++;
	  state = 5;
	}
	else
	{
	  if (nest == 0)
	  {
            attributes.push(new Array(name.toLowerCase(), attribute));
            name = '';
            attribute = '';
            state = 0;
	  }
	  else
	  {
	    attribute += c;
	    state = 5;
	  }
	}
	break;
      case 7:
	attribute += c;
	if (c == '}') nest--;
	if (c == '{') state = 6;
	else state = 5;
	break;
    }
    pos++;
  }

  if (name != '' && attribute != '')
  {
    attributes.push(new Array(name.toLowerCase(), attribute));
  }

  return attributes;
}


function getAttributeValue(attributes, tagname)
{
  for (i = 0; i < attributes.length; i++)
  {
    if (attributes[i][0] == tagname)
    {
      return attributes[i][1];
    }
  }

  return '';
}


// Convert links and element references from regular HTML format that
// can be viewed in the WYSIWYG editor to internal PrimeTime format.

function fromHtmlToText(data, basehref, convert_tags)
{
  var newdata = '';
  var pos = 0;
  var convertNextCloseLink = false;

  if (convert_tags)
  {
    while (pos < data.length)
    {
      var pos1 = data.indexOf("<", pos);
      if (pos1 >= 0)
      {
        var pos2 = data.indexOf(">", pos1 + 1);
        if (pos2 >= 0)
        {
          // A tag was found -- firstly append contents up to start of tag

          newdata += data.substr(pos, pos1 - pos);

          // Extract tag name and attributes

          var tag = data.substr(pos1 + 1, pos2 - pos1 - 1);

          if (tag.charAt(tag.length - 1) == '/')
          {
            tag = tag.substr(0, tag.length - 1);
          }
          var bits = tag.split(' ');
          var tagname = bits.shift().toLowerCase();
          var tagattr = bits.join(' ');

          if (tagname == 'img')
          {
            var attributes = parseAttributeList(tagattr);
            var tagsrc = getAttributeValue(attributes, 'src');
	    tagscr = tagsrc.replace(/&quot;/g, '"');
            var prefix = basehref + 'index.php?element=';
            if (tagsrc.substr(0, basehref.length + 18).toLowerCase() == prefix.toLowerCase())
            {
              var src = tagsrc.substr(basehref.length + 18);
              src = src.replace(/%20/g, ' ');
              src = src.replace(/\+/g, ' ');
              newdata += '{{element src="' + src + '"';
              for (i = 0; i < attributes.length; i++)
              {
                if (attributes[i][0] != 'src')
                {
                  newdata += ' ' + attributes[i][0] + '="' + attributes[i][1] + '"';
                }
              }
              newdata += '}}';
            }
            else
            {
              newdata += '<' + tag + '>';
            }
          }
          else if (tagname == 'a')
          {
            var attributes = parseAttributeList(tagattr);
            var taghref = getAttributeValue(attributes, 'href');
            var prefix = basehref + 'index.php?page=';
            var href = '';
            if (taghref.substr(0, basehref.length + 15).toLowerCase() == prefix.toLowerCase())
            {
              href = taghref.substr(basehref.length + 15);
              convertNextCloseLink = true;
              var anchor = '';
              if (href.match(/(.*)#(.*)$/))
              {
                href = RegExp.$1;
                anchor = RegExp.$2;
              }
              href = href.replace(/%20/g, ' ');
              href = href.replace(/\+/g, ' ');
	      href = href.replace(/&quot;/g, '"');
              anchor = anchor.replace(/%20/g, ' ');
              anchor = anchor.replace(/\+/g, ' ');
	      anchor = decodeURIComponent(anchor);
              newdata += '{{link page="' + href + '"';
              if (anchor != '')
              {
                newdata += ' anchor="' + anchor + '"';
              }
              for (i = 0; i < attributes.length; i++)
              {
                if (attributes[i][0] != 'href')
                {
                  newdata += ' ' + attributes[i][0] + '="' + attributes[i][1] + '"';
                }
              }
              newdata += '}}';
            }
            else
            {
              var prefix = basehref + 'index.php?element=';
              if (taghref.substr(0, basehref.length + 18).toLowerCase() == prefix.toLowerCase())
              {
                href = taghref.substr(basehref.length + 18);
                convertNextCloseLink = true;
                var anchor = '';
                if (href.match(/(.*)#(.*)$/))
                {
                  href = RegExp.$1;
                  anchor = RegExp.$2;
                }
                href = href.replace(/%20/g, ' ');
                href = href.replace(/\+/g, ' ');
	        href = href.replace(/&quot;/g, '"');
                anchor = anchor.replace(/%20/g, ' ');
                anchor = anchor.replace(/\+/g, ' ');
	        anchor = decodeURIComponent(anchor);
                newdata += '{{link element="' + href + '"';
                if (anchor != '')
                {
                  newdata += ' anchor="' + anchor + '"';
                }
                for (i = 0; i < attributes.length; i++)
                {
                  if (attributes[i][0] != 'href')
                  {
                    newdata += ' ' + attributes[i][0] + '="' + attributes[i][1] + '"';
                  }
                }
                newdata += '}}';
              }
              else
              {
                newdata += '<' + tag + '>';
              }
            }
          }
          else if (tagname == '/a')
          {
            if (convertNextCloseLink)
            {
              convertNextCloseLink = false;
              newdata += '{{/link}}';
            }
            else
            {
              newdata += '<' + tag + '>';
            }
          }
          else
          {
            newdata += '<' + tag + '>';
          }
          pos = pos2 + 1;
        }
        else
        {
          // Tag was started but not finished -- simply append remaining contents

          newdata += data.substr(pos);
          pos = data.length;
        }
      }
      else
      {
        // No new tag was found -- simply append remaining contents

        newdata += data.substr(pos);
        pos = data.length;
      }
    }

    data = newdata;

  }

  // Unescape all &quot; and &amp; within inline tags
  newdata = '';
  pos = 0;

  while (pos < data.length)
  {
    var pos1 = data.indexOf("{{", pos);
    if (pos1 >= 0)
    {
      var pos2 = data.indexOf('}}', pos1 + 2);
      if (pos2 >= 0)
      {
        pos2 += 1; // Take pointer to end of tag

        // A tag was found -- firstly append contents up to start of tag

        newdata += data.substr(pos, pos1 - pos);

        // Unescape tag name and attributes

        var tag = data.substr(pos1 + 2, pos2 - pos1 - 3);
    	tag = tag.replace(/&quot;/g, '"');
    	tag = tag.replace(/&amp;/g, '&');
        newdata += '{{' + tag + '}}';

        pos = pos2 + 1;
      }
      else
      {
        // Tag was started but not finished -- simply append remaining contents

        newdata += data.substr(pos);
        pos = data.length;
      }
    }
    else
    {
      // No new tag was found -- simply append remaining contents

      newdata += data.substr(pos);
      pos = data.length;
    }
  }

  // FCKeditor removes newlines so we made them into comment tags - remove those comments now

  newdata = newdata.replace(/<!--\n-->/g, '\n');
  newdata = newdata.replace(/<!--\r-->/g, '\r');
  newdata = newdata.replace(/<!--\r\n--><!--\r\n-->/g, '\r\n');

  return newdata;
}


// Convert links and element references from internal PrimeTime format to 
// regular HTML format that can be viewed in the WYSIWYG editor.

function fromTextToHtml(data, basehref, convert_tags)
{
  var newdata = '';
  var pos = 0;
  var convertNextCloseLink = false;

  while (pos < data.length)
  {
    var pos1 = data.indexOf("{{", pos);
    if (pos1 >= 0)
    {
      var nest_level = 0;
      var nested = false;
      var nest_pos = pos1 + 2;

      while (nest_level >= 0)
      {
        var pos_start = data.indexOf('{{', nest_pos);
        var pos2 = data.indexOf('}}', nest_pos);

        if (pos2 < 0)
        {
	  // No end of tag was found, stop looking
	  break;
	}

	if (pos_start >= 0 && pos_start < pos2)
	{
	  // A start of tag was found before the end tag ... increase nest level.
	  nest_level++;
	  nested = true;
	  nest_pos = pos_start + 2;
	}
	else
	{
	  nest_level--;
	  nest_pos = pos2 + 2;
	}
      }

      if (nest_level < 0)
      {
        pos2 += 1; // Take pointer to end of tag

        // A tag was found -- firstly append contents up to start of tag

        newdata += data.substr(pos, pos1 - pos);

        // Extract tag name and attributes

        var tag = data.substr(pos1 + 2, pos2 - pos1 - 3);

	tag = tag.replace(/^\s+/, '');
    	tag = tag.replace(/\s+$/, '');

	var standalone = false;
        if (tag.charAt(tag.length - 1) == '/')
        {
          tag = tag.substr(0, tag.length - 1);
	  standalone = true;
        }

        var bits = tag.split(' ');
        var tagname = bits.shift().toLowerCase();
        var tagattr = bits.join(' ');

        if (convert_tags && tagname == 'link')
        {
          var attributes = parseAttributeList(tagattr);
          var tagpage = getAttributeValue(attributes, 'page');
          var taganchor = getAttributeValue(attributes, 'anchor');
          var tagelement = getAttributeValue(attributes, 'element');
          convertNextCloseLink = true;
          if (tagelement != '')
          {
	    tagelement = tagelement.replace(/"/g, '&quot;');
            newdata += '<a href="' + basehref + 'index.php?element=' + tagelement;
          }
          else
          {
	    tagpage = tagpage.replace(/"/g, '&quot;');
            newdata += '<a href="' + basehref + 'index.php?page=' + tagpage;
          }

          if (taganchor != '')
          {
            newdata += '#' + encodeURIComponent(taganchor);
          }
          newdata += '"';
          for (i = 0; i < attributes.length; i++)
          {
            if (attributes[i][0] != 'page' && attributes[i][0] != 'anchor' && attributes[i][0] != 'element')
            {
    	      attributes[i][1] = attributes[i][1].replace(/"/g, '&quot;');
              newdata += ' ' + attributes[i][0] + '="' + attributes[i][1] + '"';
            }
          }
          newdata += '>';
        }
        else if (convert_tags && tagname == '/link')
        {
          if (convertNextCloseLink)
          {
            convertNextCloseLink = false;
            newdata += '</a>';
          }
          else
          {
    	    tag = tag.replace(/"/g, '&quot;');
            newdata += '{{' + tag + '}}';
          }
        }
        else if (convert_tags && tagname == 'element')
        {
          var attributes = parseAttributeList(tagattr);
          var tagsrc = getAttributeValue(attributes, 'src');
	  tagsrc = tagsrc.replace(/"/g, '&quot;');
          newdata += '<img src="' + basehref + 'index.php?element=' + tagsrc + '"';
          for (i = 0; i < attributes.length; i++)
          {
            if (attributes[i][0] != 'src')
            {
    	      attributes[i][1] = attributes[i][1].replace(/"/g, '&quot;');
              newdata += ' ' + attributes[i][0] + '="' + attributes[i][1] + '"';
            }
          }
          newdata += '>';
        }
        else
        {
    	  tag = tag.replace(/"/g, '&quot;');
          newdata += '{{' + tag + (standalone ? '/' : '') + '}}';
        }
        pos = pos2 + 1;
      }
      else
      {
        // Tag was started but not finished -- simply append remaining contents

        newdata += data.substr(pos);
        pos = data.length;
      }
    }
    else
    {
      // No new tag was found -- simply append remaining contents

      newdata += data.substr(pos);
      pos = data.length;
    }
  }

  // FCKeditor removes newlines so we make them into comment tags

  newdata = newdata.replace(/\n/g, '<!--\n-->');
  newdata = newdata.replace(/\r/g, '<!--\r-->');

  return newdata;
}


