
var TextViewHowContext = new Array();
var TextViewWhyContext = new Array();

var m_SavingDiv = null;

var m_EditFrameDiv = null;
var m_KnowdeIdList = new Array();
var m_KnowdeIdString = '';
var m_FrameContentList = '';

var m_EditFrame = null;
var m_UploadWindow = null;
var m_bTextViewWritable = new Boolean(false);
var m_bTextViewWritableModeChanged = new Boolean(false);
var m_strSelectedKGID = '';
var m_strSelectedKnowdeID = '';
var m_strPreviousSelectedKnowdeID = '';
var m_bLoadSiblingKnowde = new Boolean(false);
var m_frameHeightMargin = 30;
var m_editFrameHeightMargin = 20;

var m_textViewHighlightColor = '#FFFFFF'; //EFF0C2 F2F3CF;F3F4D7;FBFBEE;FFFFFF; FBFBEE; EAF4F7
var m_textViewTickerSelectionHighlightColor = '#bbe0e3'; // As per KGTickerControl.css
var m_noTextViewFoundContent = "<img src='images/clickedit.png'>";
var m_noTextViewFoundAddYourOwn = "<img src='images/clickedit_owntext.png'>";
var m_notLoadedText = "Loading, please wait...";
var m_clickToWriteText = "";
var m_bShowClickEditHint = 0;
var m_textViewChanged = 0;

// auto save when editing
var m_autoSaveTimeOut = null;
// in seconds
var m_autoSaveInactivePeriod = 4; 
var m_autoSaveInterval = 15; 
var m_lastAutoSaveTime = null;

var m_butTVSave; // the save button
var m_WritableButtons; // span containing all the buttons for when the text view is writable

//var m_LoadingMessage = "<div id='TextViewLoadingDiv' class='SavingMessage'><img src='Images/LoadingBar.gif'>Loading...</div>";
var m_LoadingMessage = "<table id='TextViewLoadingDiv' width=\"100%\" class='border: solid 1px Gray; font-size:xx-small; width: 120px;'><tr><td align=\"center\" style=\"font-size: xx-small\"><br/><img src=\"Images/loadingbar.gif\" /> Loading...</td></tr></table>";

var m_Content = new String();

var m_bAutoSwitchEditMode = 0;
var m_bAutoEnterEditMode = 0;

var m_textViewPreLoadAmount = 3;

var m_changeTabbedControlAfterSaving = null;

var m_textViewMode = "KNOWDEDOC";
var m_textViewDocVersion = null;

// flag to indicate whether the what text is in edit mode
var m_bWhatTextWritable = false;

/////////////////
// Processes the message that comes back from all the AJAX calls made to the Text View control
function TextView_CallbackDone(_args, _context)
{
//debugger;
  // Check for a session time out before completing the callback
  if (CheckSessionTimeout())
    return;
  
  m_bAutoSwitchEditMode = 0;
  m_bAutoEnterEditMode = 0;
  // if the string "Exception:" occurs or it is zero length then something has gone wrong
  if(_args.length == 0 || _args.indexOf("Exception:") >= 0)
    return;
    
  // First off is to convert our arguments into a proper object. What comes back should be JSON so we simply
  // evaluate it into an object
  if(_args.indexOf("{", 0) == 0)
  {
    var idx = _args.indexOf('|');
    var returnMessage = _args;
    var content = '';
    if(idx > -1)
    {
      returnMessage = _args.substr(0,idx);
      content = _args.substr(idx+1);
    }
    
    var retMessage = eval( '(' + returnMessage + ')'); 
 
    if(retMessage.OK == true)
    {
      switch(retMessage.Action)
      {
        case "Save":
          if (m_textViewMode == "KNOWDEDOC")
            HandleTextViewSaveComplete(retMessage, content);
          else if (m_textViewMode == "HKGROUPDOC")
            ShowOrHideSavingDiv(0,null,0,0);
          break; 
        case "Load":
          if(m_bTextViewWritable == false)
          {
            var m_EditFrameDiv = document.getElementById('TextViewEditFrameDiv');
            // set the global var
            m_textViewMode = retMessage.TextViewMode;
            if (m_textViewMode == "KNOWDEDOC")
            {
              m_EditFrameDiv.innerHTML = "<div class='EditMessage' align=center><img src='Images/ClickEdit.png'></div>";
            }
            else if (m_textViewMode == "HKGROUPDOC")
            {
              var values = _args.split('|');
              var content = values[1];
              
              if (!content)
                content = "";
              
              // clear the iframe div
              m_EditFrameDiv.innerHTML = "";
              // load the iframe
              HandleHKGroupDocLoad(content);
              SetTextViewToolbarWritable();
            }
          }
          break;
        case "AutoSave":
          if (m_textViewMode == "KNOWDEDOC")
            HandleTextViewSaveComplete(retMessage, content);
          else if (m_textViewMode == "HKGROUPDOC")
            ShowOrHideSavingDiv(0,null,0,0);
          break; 
      }
    }else
    {
      if(retMessage.Action == 'Save' || retMessage.Action == 'AutoSave')
      {
        HandleTextViewSaveFailure(retMessage);
        alert("Failed to save text view."); 
      }
    }
  }
  else
  {
    var values = _args.split('|');
    // set selected knowde id
    var ids = values[0].split('@');
    // get old kgId
    var oldKGID = m_strSelectedKGID;
    // set kgId
    m_strSelectedKGID = ids[0];
    // use client Id for the moment
    m_strSelectedKnowdeID = ids[2];
    
    if(oldKGID != m_strSelectedKGID)
    {
      // kg changed
      ClearTextViewValues();
    }
    
    if(m_bTextViewWritable == true)
      m_bAutoEnterEditMode = 1;
    else
    {
      if(m_bEditable == true || m_bWhatTextWritable == true)
      {
        // trigger textview editing
        m_bAutoSwitchEditMode = 1;
        // clear auto save status
        SetAutoSaveButtonStatus(-1);
      }
    }
    
    m_EditFrameDiv = document.getElementById('TextViewEditFrameDiv');

    if(m_EditFrameDiv != null)
    {
      // load all textviews
      HandleTextViewLoadAll(values[1]);
    }
    
  }
  
}

function AutoEnterEditMode()
{
  //SetupKnowdeTextViewDisableDivs();
  SetTextViewToolbarWritable();
  //setTimeout('LoadEditFrameContent()',10);
}

function ClearTextViewValues()
{
  //debugger;
  m_bLoadSiblingKnowde = false;
}

function ResetTextView()
{
  //debugger;
  m_bLoadSiblingKnowde = false;
  m_bTextViewWritable = false;

  m_KnowdeIdList = new Array();
  m_KnowdeIdString = '';
  m_FrameContentList = '';
  
  m_autoSaveTimeOut = null;
}

function AdjustEditFrameSize()
{
  if (m_EditFrame.contentWindow.document.body != null)
  {
//    m_EditFrame.style.height = m_EditFrame.contentWindow.document.body.scrollHeight + m_editFrameHeightMargin + 'px';
//    if(m_EditFrame.contentWindow.document.body.scrollWidth <= m_EditFrame.parentNode.clientWidth)
//       m_EditFrame.style.width = m_EditFrame.parentNode.clientWidth + 'px';
//    else
//       m_EditFrame.style.width = m_EditFrame.contentWindow.document.body.scrollWidth + 'px';
  }
}

function HandleTextViewLoadAll(_contentList)
{
  m_EditFrameDiv = document.getElementById('TextViewEditFrameDiv');
  
  if(m_bLoadSiblingKnowde == false)
  {
    m_KnowdeIdList = new Array();
    m_KnowdeIdString = '';
    m_FrameContentList = _contentList;
  //}
    // creat iframes
    var sidx = _contentList.indexOf('<HKTextView');
    var sidx2 = _contentList.indexOf('>', sidx);
    var sidx3 = _contentList.indexOf('</HKTextView>', sidx2);
    while(sidx != -1 && sidx2 != -1 && sidx3 != -1)
    {
      var content = _contentList.substr(sidx2+1, sidx3-(sidx2+1));
      var kid = _contentList.substr(sidx+11,sidx2-(sidx+11));
      var bWriteFrame = 0;
      
      //if(m_bLoadSiblingKnowde == false)
      //{
        m_KnowdeIdList.push(kid);
        m_KnowdeIdString += kid + ','
        
        var frame = document.createElement("iframe");
        frame.setAttribute("id", "TextViewEditFrame-k" + kid);
        frame.setAttribute("frameborder", "0");
        //frame.setAttribute("style", "width: 100%; height: 100%;");
        //frame.setAttribute("height", "97%");
        frame.setAttribute("scrolling", "yes");
        //frame.setAttribute("height", "auto");
          //frame.setAttribute("scrolling", "no");
				frame.setAttribute("height", "100%");
				frame.setAttribute("overflow", "auto");

        InsertAdjacentElement(m_EditFrameDiv,"beforeEnd", frame);
     
        if (frame.addEventListener) 
        {
          frame.contentWindow.addEventListener('focus', TextViewControl_onFocus_Timer, false);
          frame.contentWindow.addEventListener('click', TextViewControl_onFocus_Timer, false);
        } else if (frame.attachEvent) {
          frame.attachEvent('onfocus', TextViewControl_onFocus);
        }    
        
        bWriteFrame = 1;
      /*}else if(kid == m_strPreviousSelectedKnowdeID)
      {
        var frame = document.getElementById("TextViewEditFrame-k" + kid);
        if(frame != null && frame.contentWindow.document != null 
        && frame.contentWindow.document.designMode.toLowerCase() == "off" && m_bTextViewWritable)
        {
          bWriteFrame = 1;
        }
      }*/
          
      var bidx = content.toLowerCase().indexOf('<body');
      var bidx2 = content.indexOf('>');
      var bidx3 = content.toLowerCase().indexOf('</body>');
      if(bidx != -1 && bidx2 > bidx && bidx3 > bidx2)
        content = content.substr(bidx2+1, bidx3-(bidx2+1));
        
      if(content == '')
      {
        content = m_noTextViewFoundContent;
      }
      
      var divHtml = "<div id='k" + kid + "' width='100%' style='position: relative;'><div id='k" + kid + "-active' width='100%' style='top:0px;left:0px;'>";
      if (content.indexOf(m_textViewTickerSelectionHighlightColor) > -1)
        content = ReturnUnhighlightedTickerText(content);
      divHtml += content;
      divHtml += "</div></div>";

     // if(bWriteFrame == 1)
      //{
        frame.contentWindow.document.open();
        frame.contentWindow.document.write("<html><head><base target='_blank'/><link href='CSS/TextViewDocument.css' type='text/css' rel='stylesheet'/></head><body style='border: 0px;'>"); //class='PersonalisedScrollBar' 
        frame.contentWindow.document.write(divHtml);
        frame.contentWindow.document.write("</body></html>");
        frame.contentWindow.document.close();
        
        //if(m_bLoadSiblingKnowde == false)
        //{
          // don't show it yet, can't set to invisible because it will cause the div inside won't have offset height 
          frame.style.height = '0px';
        //}
     //}
      
      _contentList = _contentList.substr(sidx3+13);
      sidx = _contentList.indexOf('<HKTextView');
      sidx2 = _contentList.indexOf('>', sidx);
      sidx3 = _contentList.indexOf('</HKTextView>', sidx2);
    }
  }
  
  window.setTimeout("SetupKnowdeTextViewDivs(" + m_bAutoSwitchEditMode + "," + m_bAutoEnterEditMode + ")",15);
    
  m_bAutoSwitchEditMode = 0;
  m_bAutoEnterEditMode = 0;
        
}

function HandleHKGroupDocLoad(_content)
{
  m_EditFrameDiv = document.getElementById('TextViewEditFrameDiv');
  
  var content = _content;
  var bWriteFrame = 0;
  
  var frame = document.createElement("iframe");
  frame.setAttribute("id", "TextViewEditFrame");
  frame.setAttribute("frameborder", "0");
  frame.setAttribute("width", "100%");
  //frame.setAttribute("scrolling", "no");
  frame.setAttribute("height", "100%");
  frame.setAttribute("overflow", "auto");
  //frame.setAttribute("height", "auto");
  
  InsertAdjacentElement(m_EditFrameDiv,"beforeEnd", frame);
  
  if (frame.addEventListener)
  {
    frame.contentWindow.addEventListener('focus', TextViewControl_onFocus_Timer, false);
    frame.contentWindow.addEventListener('click', TextViewControl_onFocus_Timer, false);
  }
  else if (frame.attachEvent)
  {
    frame.attachEvent('onfocus', TextViewControl_onFocus);
  }    
  
  bWriteFrame = 1;
  
  var bidx = content.toLowerCase().indexOf('<body');
  var bidx2 = content.indexOf('>');
  var bidx3 = content.toLowerCase().indexOf('</body>');
  if(bidx != -1 && bidx2 > bidx && bidx3 > bidx2)
    content = content.substr(bidx2+1, bidx3-(bidx2+1));
  
  var divHtml = "<div width='100%' style='position: relative;'>" + content + "</div>";
  
  frame.contentWindow.document.open();
  frame.contentWindow.document.write("<html><head><base target='_blank'/><link href='CSS/TextViewDocument.css' type='text/css' rel='stylesheet'/></head><body style='border: 0px;'>"); //class='PersonalisedScrollBar' 
  frame.contentWindow.document.write(divHtml);
  frame.contentWindow.document.write("</body></html>");
  frame.contentWindow.document.close();
  
  //frame.style.height = '0px';
  
  m_bAutoSwitchEditMode = 0;
  m_bAutoEnterEditMode = 0;        
}

function SetupKnowdeTextViewDivs(_autoSwitchEditMode, _autoEnterEditMode)
{
  m_EditFrameDiv = document.getElementById('TextViewEditFrameDiv');

  var loadingDiv = document.getElementById('TextViewLoadingDiv');
  if(loadingDiv != null)
  {
    purge(loadingDiv);
    loadingDiv.parentNode.removeChild(loadingDiv);
  }

  for(var k = 0; k < m_KnowdeIdList.length; k++)
  {
    var id = m_KnowdeIdList[k];
    SetupKnowdeTextViewDiv(id);
  }
  
  if(_autoSwitchEditMode != null && _autoSwitchEditMode == 1 && (m_bEditable == true || m_bWhatTextWritable == true) && m_bTextViewWritable != true)
    SwitchTextViewEditing(); //window.setTimeout("SwitchTextViewEditing()",1);
  else if(_autoEnterEditMode != null && _autoEnterEditMode == 1 && m_bTextViewWritable == true)
    AutoEnterEditMode(); //window.setTimeout("AutoEnterEditMode()",1);
}

function SetupKnowdeTextViewDiv(_id)
{
  var editFrame = document.getElementById("TextViewEditFrame-k"+_id);
  if(editFrame != null)
  {
    editFrame.style.height = '100%';
    editFrame.style.width = '100%';
    editFrame.style.overflow = 'auto';
    // commented out for now as it's not working if put the textview control in overlay control
    var div = editFrame.contentWindow.document.getElementById('k'+_id);
    var adiv = editFrame.contentWindow.document.getElementById('k' + _id + '-active');
    var gdiv = editFrame.contentWindow.document.getElementById('k' + _id + '-disable');

    if(div != null)
    {
//       if(adiv != null)
//       {
//          editFrame.style.height = adiv.offsetHeight + m_frameHeightMargin + 'px'; 
//       }
//       else
//       {
//        editFrame.style.height = div.offsetHeight + m_frameHeightMargin + 'px'; 
//       }
    }else if(editFrame.contentWindow.document != null && editFrame.contentWindow.document.body != null
            && editFrame.contentWindow.document.body.scrollHeight > 0)
    {
//      if(editFrame.contentWindow.document.designMode.toLowerCase() == 'on')
//      {
//        editFrame.style.height = editFrame.contentWindow.document.body.scrollHeight + m_frameHeightMargin + m_editFrameHeightMargin + 'px';
//        //debugger;
//        if(editFrame.contentWindow.document.body.scrollWidth <= editFrame.parentNode.clientWidth)
//          editFrame.style.width = editFrame.parentNode.clientWidth + 'px';
//        else
//          editFrame.style.width = editFrame.contentWindow.document.body.scrollWidth + 'px';
//      }
//      else
//        editFrame.style.height = editFrame.contentWindow.document.body.scrollHeight + m_frameHeightMargin + 'px';
    }
    // resize gray out div if exists
    if(gdiv != null)
    {
      if(editFrame.style.height != '' && editFrame.style.width != '')
      {
        gdiv.style.height = editFrame.style.height;
        gdiv.style.width = editFrame.style.width;
      }
    }
    //div.style.display = 'block';
    // highlight selected knowde textview if in read only mode
    if(div != null && _id == m_strSelectedKnowdeID)
    {
      if(m_bTextViewWritable == false)
        div.style.backgroundColor = m_textViewHighlightColor;
        
      // auto scroll to the position
      if(m_EditFrameDiv == null)
        m_EditFrameDiv = document.getElementById('TextViewEditFrameDiv');
      if(m_EditFrameDiv != null && editFrame.offsetTop >= 0)
        m_EditFrameDiv.scrollTop  = editFrame.offsetTop;

    }else if(div != null && m_bTextViewWritable == false)
    {
      div.style.backgroundColor = ''; 
    }
  }
}

function TextViewDivResize()
{   
  m_EditFrameDiv = document.getElementById("TextViewEditFrameDiv");
  if(m_EditFrameDiv != null && m_KnowdeIdList !=  null && m_KnowdeIdList.length > 0)
    SetupKnowdeTextViewDivs();
}

function SetupKnowdeTextViewDisableDivs()
{
  if(m_KnowdeIdList != null && m_KnowdeIdList.length > 0)
  {
    for(var k = 0; k < m_KnowdeIdList.length; k++)
    {
      var id = m_KnowdeIdList[k];
      SetupKnowdeTextViewDisableDiv(id);
    }
  }
}

function SetupKnowdeTextViewDisableDiv(_id)
{
  var editFrame = document.getElementById("TextViewEditFrame-k"+_id);
  if(editFrame != null)
  {
    var div = editFrame.contentWindow.document.getElementById('k'+_id);
    var adiv = editFrame.contentWindow.document.getElementById('k' + _id + '-active');
    var gdiv = editFrame.contentWindow.document.getElementById('k' + _id + '-disable');

    if(m_bTextViewWritable == true)
    {
      // edit mode, create greyout div for read only knowdes' textviews
      if( _id != m_strSelectedKnowdeID)
      {
        if(div != null && adiv != null && gdiv == null)
        { 
          // create greyout layer
          gdiv = editFrame.contentWindow.document.createElement("div");
          gdiv.setAttribute("id",'k' + _id+"-disable");
          gdiv.style.width = adiv.offsetWidth; // editFrame.clientWidth; // div.offsetWidth + 'px';
          gdiv.style.height = adiv.offsetHeight; //editFrame.clientHeight; // div.offsetHeight + 'px';
          gdiv.style.position = "absolute";
          gdiv.style.padding = "0px 0px 0px 0px";
          gdiv.style.top = "0px";
          gdiv.style.left = "0px";
          gdiv.style.background = 'white';
          gdiv.style.opacity = .70;
          gdiv.style.filter = 'alpha (opacity=70)';
          
          InsertAdjacentElement(adiv,"afterEnd", gdiv);
        }else
        {
          //debugger;
        }
      }
    }else
    {
      // read only mode, clear greyout div
      if(div != null && adiv != null && gdiv != null)
      {
        purge(gdiv);
        div.removeChild(gdiv);
      }
    }
    
  }
}

function GetDefaultTextViewContentWithTitle(_knowdeID, _title, _withImg, _image)
{
  //debugger;
  // get current knowde text
  var defaultContent = '';
  var kndText = _title;
  if(kndText == null || kndText == '')
  {
  	var kndObj = (returnKnowdesWithClientIDAttribute(_knowdeID))[0];
    if(kndObj != null)
    {
      kndText = GetKnowdeFullText(kndObj); 
    }
    else
    {
      // what or whatIs
      if(globalLastHighlightedWhat != null)
      {
        kndText = GetInnerText(globalLastHighlightedWhat);
        var verbText = GetVerbTextForKnowde(CurrentWhatRootKnowde);
        kndText = ConcatWords(verbText, kndText);
      }
    }
  }
  if(_withImg == 1 && (_image == null || _image.length <= 0))
    _image = m_clickToWriteText;
    
  if(kndText != '')
  {
     defaultContent = "<h3 id='knowdeTitle'>" + kndText + "</h3>";
     defaultContent += "<div style='MARGIN-LEFT: 10px;'><p>"
     if(_withImg == null || _withImg == 1)
      defaultContent += _image;
     defaultContent += "</p></div>";
   }else
    defaultContent = _image;
    
  return defaultContent;
}

function WrapTextViewContentWithTitle(_knowdeID, _title, _content)
{
  // some text view format will causing the textview common object return the body tag as well
  if(_content.toLowerCase().indexOf('<body') != -1)
  {
    var btag1 = _content.toLowerCase().indexOf('<body');
    if(btag1 == 0)
    {
      var btag2 = _content.toLowerCase().indexOf('>', 0);
      if(btag2 > 0)
      {
        // get rid of body start tag
        _content = _content.substring(btag2+1);
        // get rid of body end tag
        var btag3 = _content.toLowerCase().indexOf('</body>');
        if(btag3 > 0)
          _content = _content.substring(0, btag3) + _content.substring(btag3+7);
      }
      
    }
  }

  var defaultContent = _content;
  var kndText = _title;
  if(kndText != '' && _content != null)
  {
     var lc = _content.toLowerCase().replace(/^(<br\/>|<br \/>|<p\/>|<p><\/p>|<p \/>|<p><br \/><\/p>|<p><br\/><\/p>)+/i,'');
     var sidx = lc.indexOf('<h3');
     var cidx = lc.indexOf('/>',sidx);
     var cidx2 = lc.indexOf('>',sidx);
     var cidx3 = lc.indexOf('</h3>',sidx);
     if(sidx == 0 && cidx3 != -1 && cidx2 != -1 && cidx3 >= cidx2+1 && (cidx == -1 || cidx > cidx3)
       && lc.substring(sidx, cidx2).indexOf('knowdetitle') != -1)
     {
        // if the title tag already exists and is empty
        var title = lc.substring(cidx2+1, cidx3);
        var count = 0;
        title = title.replace(' ','');
        title = title.replace('&nbsp;','');
        for(var ci=0; ci<title.length; ci++ )
        {
          if(title.charCodeAt(ci) == 160)
          {
            // get rid of charcode 160 white space
          }else
          {
            count++;
            break;
          }
        }
        if(count <= 0)
        {
          // put the knowde title in
          var titleTag = lc.substring(sidx, cidx3+5);
          var s1 = _content.toLowerCase().indexOf(titleTag);
          defaultContent = _content.substring(0, s1) + "<h3 id='knowdeTitle'>" + kndText + "</h3>" + _content.substring(s1 + titleTag.length);
        }
     }
     else
     {
       // add the title in
       defaultContent = "<h3 id='knowdeTitle'>" + kndText + "</h3>";
       defaultContent += "<div style='MARGIN-LEFT: 10px;'><p>"
       defaultContent += _content;
       defaultContent += "</p></div>";
     }
  }
    
  return defaultContent;
  
  
}

function CheckTextViewHasTitle(_knowdeID, _title, _content)
{
  var hasTitle = true;
  var lc = _content.toLowerCase().replace(/^(<br\/>|<br \/>|<p\/>|<p><\/p>|<p \/>|<p><br \/><\/p>|<p><br\/><\/p>)+/i,'');
  // some text view format will causing the textview common object return the body tag as well
  if(lc.indexOf('<body') != -1)
  {
    var btag1 = lc.indexOf('<body');
    if(btag1 == 0)
    {
      var btag2 = lc.indexOf('>', 0);
      if(btag2 > 0)
        lc = lc.substring(btag2+1);
    }
    else
    {
      return true; // not sure how to deal with this format yet, so return true by default
    }
  }
  
  if(lc.indexOf('<h1') == 0 || lc.indexOf('<h2') == 0 || lc.indexOf('<h3') == 0)
  {
    var cidx = lc.indexOf('/>',0);
    var cidx2 = lc.indexOf('>',0);
    var cidx3 = lc.indexOf('</',0);
    // if the tag is not empty
    if(cidx3 != -1 && cidx2 != -1 && cidx3 > cidx2+1 && (cidx == -1 || cidx > cidx3))
    {
       var title = lc.substring(cidx2+1, cidx3);
        var count = 0;
        title = title.replace(' ','');
        title = title.replace('&nbsp;','');
        for(var ci=0; ci<title.length; ci++ )
        {
          if(title.charCodeAt(ci) == 160)
          {
            // get rid of charcode 160 white space
          }else
          {
            count++;
            break;
          }
        }
      if(count <= 0)
      {
        hasTitle = false;
      }
    }
    else
    {
      hasTitle = false;
    }
  }
  else
  {
    hasTitle = false;
  }
    
  return hasTitle;

}

function GetCurrentKnowdeTextForTextView(_knowdeID)
{
	var kndText = '';
	// If there are reused knowdes just return the first one
  var kndObj = (returnKnowdesWithClientIDAttribute(_knowdeID))[0];

  if (kndObj != null && kndObj.id.indexOf('knowde') != -1)
  {
     kndText = GetKnowdeFullText(kndObj); 
  }
  else if (kndObj != null && kndObj.id.indexOf('what') != -1)
  {
      kndText = GetInnerText(kndObj);
      var verbText = GetVerbTextForKnowde(CurrentWhatRootKnowde);
      kndText = ConcatWords(verbText, kndText);
  }
  
  return kndText;
}

function GetDefaultTextViewContent(_knowdeID, _withImg)
{
  // get current knowde text
  var defaultContent = '';
  var kndText = GetCurrentKnowdeTextForTextView(_knowdeID);

  if(kndText != '')
  {
     defaultContent = "<h3 id='knowdeTitle'>" + kndText + "</h3>";
     defaultContent += "<div style='MARGIN-LEFT: 10px;'><p>"
     if(_withImg == null || _withImg == 1)
      defaultContent += m_clickToWriteText;
     defaultContent += "&nbsp;</p></div>"; // need the space here for firefox otherwise can focus on the paragraph
   }else
    defaultContent = m_clickToWriteText;
    
  return defaultContent;
}

function UpdateTextViewKnowdeTitle(_oldTitle, _newTitle)
{
  //debugger;
  m_EditFrame = document.getElementById("TextViewEditFrame-k"+m_strSelectedKnowdeID);
  if(m_EditFrame != null && m_EditFrame.contentWindow && m_EditFrame.contentWindow.document != null)
  {
    var titleHeading = m_EditFrame.contentWindow.document.getElementById('knowdeTitle');
    if(titleHeading == null)
      return;
    // only auto update the title if it's the default one which is the knowde text
    var tvKndTitle = GetInnerText(titleHeading).toLowerCase();
    var oldTitle = _oldTitle.toLowerCase();
    tvKndTitle = TrimString(tvKndTitle);
    tvKndTitle = tvKndTitle.replace('\u00A0','<@HKSpace@>');
    tvKndTitle = tvKndTitle.replace(' ','<@HKSpace@>');
    oldTitle = TrimString(oldTitle );
    oldTitle = oldTitle.replace('\u00A0','<@HKSpace@>');
    oldTitle = oldTitle.replace(' ','<@HKSpace@>');
    if(tvKndTitle == oldTitle)
    {
      SetInnerText(titleHeading,_newTitle);
      if(m_bShowClickEditHint == 0)
        TriggerAutoSave();
    }
  }
}

////////////////////////
// Inserts the supplied content into the text view
// _content: The contents of the <body> element to load
function HandleTextViewLoad(_content, _knowdeID)
{
//debugger;
  var frame = document.getElementById("TextViewEditFrame-k" + _knowdeID);
  if(frame != null && frame.contentWindow.document != null)
  {      
    if(_content == '')
    {
      if(m_bTextViewWritable == true)
      {
        _content = GetDefaultTextViewContent(_knowdeID);
      }
      else 
        _content = m_noTextViewFoundContent;
    }

    if(m_bTextViewWritable == true)
    {
      var divHtml = _content;
    }else
    {
      var divHtml = "<div id='k" + _knowdeID + "' width='100%' style='position: relative;'><div id='k" + _knowdeID + "-active' width='100%'>";
      divHtml += _content;
      divHtml += "</div></div>";
    }

    frame.contentWindow.document.write("<html><head><link href='CSS/TextViewDocument.css' type='text/css' rel='stylesheet'/></head><body style='border: 0px;'>"); //class='PersonalisedScrollBar' 
    frame.contentWindow.document.write(divHtml);
    frame.contentWindow.document.write("</body></html>");
  }
  
  //window.setTimeout("SetupKnowdeTextViewDiv('" + m_strSelectedKnowdeID + "')",10);

}

////////////////////////////////
// Handles the saving failure message sent back after a save AJAX call is made
function HandleTextViewSaveFailure(message)
{
   if(m_butTVSave != null)
  {          
    m_butTVSave.src = "Images/KGButtonToolbar/FailedSaveTextView.png";
    m_butTVSave.title = "Fail to Save the Document";
    //TextViewButtonOut(m_butTVSave)
  }
  
  ShowOrHideSavingDiv(0,null,0,0);
  
  if(m_changeTabbedControlAfterSaving != null && m_changeTabbedControlAfterSaving != '')
  {
    m_changeTabbedControlAfterSaving = null;
  }
}

////////////////////////////////
// Handles the saving complete message sent back after a save AJAX call is made
function HandleTextViewSaveComplete(message, content)
{
  
  //debugger;
  
  // don't change edit mode if switching between sibling knowdes
  if(m_bLoadSiblingKnowde == false)
  {
    m_bTextViewWritable = false;
    m_bTextViewWritableModeChanged = true;
  }
  // we need to set a timeout because if we don't the AJAX calls get themselves in a muddle and crashes
  globalTextViewPageLoaded = true;
  if(message.Repopulate == true && (message.Action != 'AutoSave' || m_bLoadSiblingKnowde == true))
  {        
      HandleTextViewLoad(content, message.KnowdeID);

      // need to turn off design mode  
      var frame = document.getElementById("TextViewEditFrame-k" + message.KnowdeID);
      if(frame != null && frame.contentWindow.document.designMode.toLowerCase() != "off")
        frame.contentWindow.document.designMode = "off";
      // make sure the grey out div is applied.
      // Because the handleLoadAllKnowdes callback could be finished quicker than the SaveComplete callback when switching knowdes in edit mode
      setTimeout('SetupKnowdeTextViewDisableDiv(\'' + message.KnowdeID + '\')',10);
      setTimeout("SetupKnowdeTextViewDiv('" + message.KnowdeID + "')",20);
  }else if(message.Repopulate == false && m_bTextViewWritable == true)
  {
    if(m_butTVSave != null)
    {
      m_butTVSave.src = "Images/KGButtonToolbar/StopWritingTextView.png";
      m_butTVSave.title = "Save and Stop Writing Document";
    }
    
    if(EditFrameContentWindowExists() && m_EditFrame.contentWindow.document.body.innerHTML == '')
      m_EditFrame.contentWindow.document.body.innerHTML = GetDefaultTextViewContent(message.KnowdeID);   

    if(message.Action == 'AutoSave')
    {
      var clTime = new Date();
      var clUtc = clTime.getTime() + (clTime.getTimezoneOffset() * 60000 );
      // reset timmer
      m_lastAutoSaveTime = clUtc;
    }
  }

  
  if(message.Action != 'AutoSave')
  {
    setTimeout("SetUpTextView()", 100);
  }
  m_Content = "";

  ShowOrHideSavingDiv(0,null,0,0);
  
  
  if(window.Active_KGID)
  {
      m_bLoadSiblingKnowde = false;
      m_repopulate = "false";  
      setTimeout("KGMapToolbarControl_CallbackTrigger('" + Active_KGID + "');", 1000);    
  }

  /*if(m_changeTabbedControlAfterSaving != null && m_changeTabbedControlAfterSaving != '')
  {
    // auto change tab
    setTimeout("KGTabbedWindowsControl_SelectTabById('" + m_changeTabbedControlAfterSaving + "')", 20);
    m_changeTabbedControlAfterSaving = null;
  }*/
}

////////////////////////////
// Method that handles any error in the AJAX callbacks
function TextView_CallbackError(args, context)
{
  // Here we are dealing with authentication timeout before callback, 
  // the message from the server is 'elogin' signify an error with 
  // authentication. The response will be trimmed to form the args 
  // 'login' here..... 
  if(args == 'login')
  {
    window.location='home.aspx';
  }
  else
  {
    alert('There has been an error in callback.');
  }
}

/////////////////
// Sets up the text view ready for use
function SetUpTextView()
{  
  if (globalTextViewPageLoaded == null || globalTextViewPageLoaded == false)
    return;  
    //debugger;
  m_EditFrameDiv = document.getElementById("TextViewEditFrameDiv");

  if (m_EditFrameDiv != null)
  {
    m_butTVSave = null;//KGButtonToolbar_getWriteTextViewButton(); //document.getElementById("buttonTVSave");
    m_WritableButtons = document.getElementById("TVWriteableButtons");
    
    if(m_bTextViewWritable == true)
    {
      DisplayTextViewInTab('TextViewEdit', '');
      SetTextViewToolbarWritable();
    }
    else
    {
      if(!m_bEditable)
        DisplayTextViewInTab('TextViewReadOnly', '');
      SetTextViewToolbarReadOnly();
    }
    
     //setTimeout("ResizeTextView()",300);
  }
}

/*function ResizeTextView()
{
	m_EditFrameDiv = document.getElementById("TextViewEditFrameDiv");
  if (m_EditFrameDiv != null)
  {
		m_butTVSave = KGButtonToolbar_getWriteTextViewButton();//document.getElementById("buttonTVSave");
		if(m_bTextViewWritable == true || m_butTVSave != null)
		{
			m_EditFrameDiv = document.getElementById("TextViewEditFrameDiv");
			m_toolBar = document.getElementById("TextViewToolbar");
			var toolBarHeight = 10;
			if(m_toolBar != null)
			  toolBarHeight += m_toolBar.clientHeight;
			var paneBottom = document.getElementById("Splitter1_pane_1_1");
			if (paneBottom.clientHeight - toolbarHeight > 0)			
			  m_EditFrame.style.height = paneBottom.clientHeight - toolbarHeight + "px";
			else
			  m_EditFrame.style.height = 0;
		}
	}
}*/

// Sets up the toolbar so that is displays the editing functionality
function SetTextViewToolbarWritable()
{
  
  //TurnOffOldEditFrame();
  m_EditFrameDiv = document.getElementById('TextViewEditFrameDiv');
  // don't auto save if user move the mouse out of the area, 
  // instead, auto save if user move the mouse to the category bar and the head area so if they navigate out of the editing mode
  // they won't lost the changes
  /*if(m_EditFrameDiv != null)
  {
    if (m_EditFrameDiv.addEventListener)
    {
      m_EditFrameDiv.addEventListener('mouseout', TextViewControl_onMouseOut,false);
    }
    else
    {
      m_EditFrameDiv.attachEvent("onmouseout",   TextViewControl_onMouseOut);
    }
  }*/
  if (m_textViewMode == "KNOWDEDOC")
    m_EditFrame = document.getElementById("TextViewEditFrame-k"+m_strSelectedKnowdeID);
  else if (m_textViewMode == "HKGROUPDOC")
    m_EditFrame = document.getElementById("TextViewEditFrame");
  
  if(m_EditFrame != null)
  {
    if(m_EditFrame.contentWindow.document.designMode.toLowerCase() != "on")
      m_EditFrame.contentWindow.document.designMode = "on";

//    if (m_textViewMode == "KNOWDEDOC")
//    {
//     if(m_EditFrame.contentWindow.document.body != null)
//        m_EditFrame.style.height = m_EditFrame.contentWindow.document.body.scrollHeight + m_editFrameHeightMargin + 'px';
//     else
//        m_EditFrame.style.height = parseInt(m_EditFrame.style.height.replace('px','')) + m_editFrameHeightMargin + 'px';
//    }
//    else if (m_textViewMode == "HKGROUPDOC")
//    {
//      setTimeout("AdjustEditFrameSize()", 1);
//    }
    var rte = m_EditFrame.contentWindow.document;
    if (rte.addEventListener)
    {
      rte.addEventListener('keyup', TextViewControl_KeyPress,false);
      rte.addEventListener('mouseup', TextViewControl_onMouseUp,false);
      rte.addEventListener('focus', TextViewControl_onFocus_Timer,false); //for Opera
      rte.addEventListener('click', TextViewControl_onFocus_Timer,false); //for Safari
      // when press enter, enter single line break instead of create new paragraph
      //rte.addEventListener('keydown', TextViewControl_KeyDown, false); 
    }
    else
    {
      rte.attachEvent('onkeyup', function (){TextViewControl_KeyPress()});
      rte.attachEvent('onmouseup', function (){TextViewControl_onMouseUp()});

      // when press enter, enter single line break instead of create new paragraph
      //rte.attachEvent('onkeydown', TextViewControl_KeyDown);
    }
    
    if(m_butTVSave != null)
    {
      m_butTVSave.src = "Images/KGButtonToolbar/StopWritingTextView.png";
      m_butTVSave.title = "Save and Stop Writing Document";
    }
    
    if(m_WritableButtons != null)
      m_WritableButtons.style.display = "inline";
    
    if(m_bTextViewWritable == false)
      m_bTextViewWritableModeChanged = true;
      
    if (m_textViewMode != "HKGROUPDOC")
      m_bTextViewWritable = true;
    
    var button = document.getElementById("KGButtonToolbar_ShowTicker");
    if (button)
      button.className = "ButtonToolbar_TextButtonDivInactive";
    // need to set it to active if the active frame's inner html has ticker tags set
    
    if (m_textViewMode == "KNOWDEDOC")
    {
      SetupKnowdeTextViewDisableDivs();
      setTimeout('LoadEditFrameContent()',10);
    }
    
    // update the button toolbar
    if(m_bTextViewWritableModeChanged == true)
    {
      //setTimeout("KGButtonToolbar_StartTextViewEditing()", 20);
    }
      
    m_bTextViewWritableModeChanged = false;
  }
}

var textViewFocusTimer;
//make sure the function is only called once because now it has to be attached to a few events
function TextViewControl_onFocus_Timer()
{
  clearTimeout(textViewFocusTimer);
  textViewFocusTimer = setTimeout(TextViewControl_onFocus,10);
}

function LoadEditFrameContent()
{
  //debugger;
  var editFrame = document.getElementById("TextViewEditFrame-k" + m_strSelectedKnowdeID);
  if(editFrame == null)
  {
    // hasn't loaded yet, wait a while
    setTimeout('LoadEditFrameContent()',10);
    return;
  }
  
  var div = editFrame.contentWindow.document.getElementById('k' + m_strSelectedKnowdeID);
  var adiv = editFrame.contentWindow.document.getElementById('k' + m_strSelectedKnowdeID + '-active');
  if(editFrame.contentWindow.document.designMode.toLowerCase() == 'on')
  {
    if(editFrame.contentWindow.document.body == null)
    {
      // haven't loaded yet, wait a while
      setTimeout('LoadEditFrameContent()',10);
      return;
    }
    
    if(div != null && adiv != null)
    {
      if(adiv.innerHTML.toLowerCase().indexOf('images/clickedit.png') == -1)
      {
        var content = adiv.innerHTML;
        var kndText = GetCurrentKnowdeTextForTextView(m_strSelectedKnowdeID);
        if(kndText != '')
        {
//          if(CheckTextViewHasTitle(m_strSelectedKnowdeID, kndText, content) == false)
//             content = WrapTextViewContentWithTitle(m_strSelectedKnowdeID, kndText, content);
        }
        editFrame.contentWindow.document.body.innerHTML = content; 
        //editFrame.contentWindow.document.body.focus();
      }
      else
      {
        var tvc = GetDefaultTextViewContent(m_strSelectedKnowdeID);

        if (navigator.appName == "Microsoft Internet Explorer")
        {
          editFrame.contentWindow.document.body.innerHTML = tvc;
        }
        else
        {
          editFrame.contentWindow.document.body.innerHTML = tvc.replace('&nbsp;','<br />');
        }
        // auto focus, but only if we arent currently adding a knowde 
        if(globalAutoFocusTextView)
        {
					placeCursorAtEnd(editFrame.contentWindow.document.body);
				}
        //editFrame.contentWindow.document.body.focus();
        //m_bShowClickEditHint = 1;
      }
      
      // fixes bug where textview iframe disappears on edit mode with text view visible, resize tab with splitter or open/close whats, then change knowde (9149, #779)
      KGTextTabControl_AdjustTextViewControlSize();
      // fixes bug where the textview iframe doesnt resize when editing the same knowde for a second time
      TextViewDivResize()
      //editFrame.contentWindow.focus();
      
    }
    m_textViewChanged = 0;
 }

}

function placeCursorAtStart(el) 
{
  if (el.setSelectionRange) 
  {
    el.setSelectionRange(0, 0);
  } 
  else if (el.createTextRange) 
  {
    var range = el.createTextRange();
    range.collapse(true);
    range.moveEnd('character', 0);
    range.moveStart('character', 0);
    range.select();
  }
}


function placeCursorAtEnd(el) 
{
  var len = el.innerHTML.length;
  if (el.setSelectionRange) 
  {
    el.setSelectionRange(len, len);
  } 
  else if (el.createTextRange) 
  {
    var range = el.createTextRange();
    range.collapse(true);
    range.moveEnd('character', len);
    range.moveStart('character', len);
    range.select();
  }
}


///////////////////////
// sets the toolbar to be the saving version
function SetTextViewToolbarSaving()
{
  if(m_butTVSave != null)
  {          
    m_butTVSave.src = "Images/KGButtonToolbar/SavingTextView.png";
    m_butTVSave.title = "Saving Document...";
    //TextViewButtonOut(m_butTVSave)
  }
  
  if(m_WritableButtons != null)
    m_WritableButtons.style.display = "none";
    
  ShowOrHideSavingDiv(1, null, 0, 0);
}

///////////////////////
// Sets up the toolbar so that is is read-only
function SetTextViewToolbarReadOnly()
{
  //TurnOffOldEditFrame();
  
  m_EditFrame = document.getElementById("TextViewEditFrame-k"+m_strSelectedKnowdeID);
  if(m_EditFrame != null && m_EditFrame.contentWindow.document.designMode.toLowerCase() != "off"){
    m_EditFrame.contentWindow.document.designMode = "off";
  }
  
  if(m_butTVSave != null)
  {          
    m_butTVSave.src = "Images/KGButtonToolbar/WriteTextView.png";
    m_butTVSave.title = "Start Writing Document";
  }
  
  if(m_WritableButtons != null)
    m_WritableButtons.style.display = "none";
  
  if(m_bTextViewWritable == true)
    m_bTextViewWritableModeChanged = true;

  m_bTextViewWritable = false;
  
  SetupKnowdeTextViewDisableDivs();
  
  // update the button toolbar
  if(m_bTextViewWritableModeChanged == true)
  {  
    //setTimeout("SetupKnowdeTextViewDivs()",10);
    setTimeout("SetupKnowdeTextViewDiv('" + m_strSelectedKnowdeID + "')",10);
    //setTimeout("KGButtonToolbar_StopTextViewEditing()", 20);
  }
    
  m_bTextViewWritableModeChanged = false;
}

function TurnOffOldEditFrame()
{
 var oldEditFrame = null;
 if(m_strPreviousSelectedKnowdeID != '')
  oldEditFrame = document.getElementById("TextViewEditFrame-k"+m_strPreviousSelectedKnowdeID);
 if(oldEditFrame != null && m_strPreviousSelectedKnowdeID != m_strSelectedKnowdeID
    && oldEditFrame.contentWindow.document != null && oldEditFrame.contentWindow.document.designMode.toLowerCase() == "on")
     oldEditFrame.contentWindow.document.designMode = "off"

}

function ChangeSelectedTextView(_selectedKnowdeID)
{
  m_strPreviousSelectedKnowdeID = m_strSelectedKnowdeID;
  m_strSelectedKnowdeID = _selectedKnowdeID;
  
  if(m_strPreviousSelectedKnowdeID == m_strSelectedKnowdeID)
    return false;
  else
    return true;
}

function SwitchTextViewEditing()
{
//debugger;
  if(m_autoSaveTimeOut !=  null)
    clearTimeout(m_autoSaveTimeOut);
  m_bLoadSiblingKnowde = false;
  SaveTextView();
}

/////////////////////
// Kicks off the loading of the text view
function LoadTextView()
{
  //debugger;
  m_EditFrameDiv = document.getElementById('TextViewEditFrameDiv');
    
  // only show loading image if it's a full reload
  if(m_EditFrameDiv != null && m_bLoadSiblingKnowde == false)
    m_EditFrameDiv.innerHTML = m_LoadingMessage;
  
  if(m_bLoadSiblingKnowde == false)
    SetUpTextView();
    
  var args = "Action=Load";
  if(m_bLoadSiblingKnowde == true)
    args += "|LoadSiblingKnowde=true";
    
  // if the docVersion is not null add it to the callback args
  if (m_textViewDocVersion != null)
    args += "|DocumentVersion=" + m_textViewDocVersion;
  
  KGTextViewEditingToolbar_ChangeEditbarMode("TextViewReset");
  
  TextView_CallbackTrigger(args);
}

function AutoSaveTextView()
{
  if(m_EditFrame != null && m_bTextViewWritable)
  {
    //debugger;
    // check whether reach interval
    var clTime = new Date();
    var clUtc = clTime.getTime() + (clTime.getTimezoneOffset() * 60000 );
    if((clUtc - m_lastAutoSaveTime)/1000 < m_autoSaveInterval)
    {
      // not reach the interval yet
      m_autoSaveTimeOut =  setTimeout('AutoSaveTextView()', m_autoSaveInterval * 1000 - (clUtc - m_lastAutoSaveTime) + 1000);
      return;
    }
    
    // reset timmer
    m_lastAutoSaveTime = clUtc;
    
    var div = m_EditFrame.contentWindow.document.getElementById('k' + m_strSelectedKnowdeID);
    var adiv = m_EditFrame.contentWindow.document.getElementById('k' + m_strSelectedKnowdeID + '-active');
    var content = '';
        
    if(adiv != null)
      content = adiv.innerHTML;
    else if(div != null)
      content = div.innerHTML;
    else
      content = m_EditFrame.contentWindow.document.body.innerHTML;
        
    //debugger;
    if(content.length > 0)
    {
      m_bLoadSiblingKnowde = true;
      if (m_textViewMode == "KNOWDEDOC")
      {
        SaveTextView('Action=AutoSave|Repopulate=false|KGId=' + m_strSelectedKGID + '|KnowdeId=' + m_strSelectedKnowdeID + '|Changed=true');
      }
      else if (m_textViewMode == "HKGROUPDOC")
        SaveHKGroupTextView('Action=AutoSave');
    }
  }
  else
  {
    if(m_autoSaveTimeOut != null)
      clearTimeout(m_autoSaveTimeOut);
  }
}

///////////////
// Saves the text view to the server
function SaveTextView(_args)
{
  //debugger;
  // The text view may not be writable, if this is the case then just make it all writable and return
  if(m_bTextViewWritable == false)
  {
    m_bTextViewWritableModeChanged = true;
    DisplayTextViewInTab('TextViewEdit', '');
    SetTextViewToolbarWritable(); 
    return;
  }
  
  if(TextviewKeypressTimeout != null)
    clearTimeout(TextviewKeypressTimeout);
  
   //m_EditFrame.contentWindow.document.contentEditable = "false";

  // grab the document text
  //var text = m_EditFrame.contentWindow.document.body.innerHTML;
  var div = m_EditFrame.contentWindow.document.getElementById('k' + m_strSelectedKnowdeID);
  var adiv = m_EditFrame.contentWindow.document.getElementById('k' + m_strSelectedKnowdeID + '-active');
  
  if(m_EditFrame.contentWindow.document.body.innerHTML.toLowerCase().indexOf('images/clickedit') != -1)
    m_EditFrame.contentWindow.document.body.innerHTML = '';   

  if(adiv != null)
    m_Content = adiv.innerHTML;
  else if(div != null)
    m_Content = div.innerHTML;
  else {
  	m_Content = m_EditFrame.contentWindow.document.body.innerHTML;
  	m_Content = m_Content.replace('knowdeTitle', '"knowdeTitle"');
  }
  SetTextViewToolbarSaving();
  
//debugger;
  var requiredSaving = 1;
  var textVersionEdited = 0;
  if(_args != null && _args.indexOf('AutoSave') != -1)
  {
     if(m_autoSaveTimeOut != null)
        clearTimeout(m_autoSaveTimeOut);
    
     requiredSaving = m_textViewChanged; //no changes made since last save
     
    if(m_textViewChanged == 1 && m_textViewMode == "KNOWDEDOC") // text version text changed
      textVersionEdited = 1;
  }
  m_textViewChanged = 0;
   
  // get rid of tailing two line breaks that added in edit mode
  //if(m_Content.substr(m_Content.length - 10, 10) == '<br/><br/>')
    //m_Content = m_Content.substr(m_Content.length - 10, 10);

  // display the saving icon
  //m_EditFrame.contentWindow.document.body.innerHTML = "<div class='SavingMessage'><img src='Images/LoadingBar.gif'>&nbsp;Please wait while we save your changes...</div>";
  
  if(requiredSaving == 1)
  {
    // make the ajax call
    // default action
    var args = "Action=Save|KGId=" + m_strSelectedKGID + "|KnowdeId=" + m_strSelectedKnowdeID + "|";
    // if pass in specific action, use them instead
    if(_args != null && _args.length > 0)
      args = _args + "|";
    
    if(textVersionEdited == 1) // text version text changed
    {
       //m_KnowdeDocVersionArray = m_buttonToolbar_docVersionSelect.Edited(m_KnowdeDocVersionArray);
       if(args.indexOf('|Changed=') == -1)
        args += 'Changed=true|';
    }

    args += "Contents=" + m_Content;
    
    // if the docVersion is not null add it to the callback args
    if (m_textViewDocVersion != null)
      args += "|DocumentVersion=" + m_textViewDocVersion;
          
    TextView_CallbackTrigger(args); 
    
  }else
  {
    // don't callback, just refresh the content
    var returnMessage = '{"KGID":"0","KnowdeID":"0","Action":"AutoSave","OK":true,"Repopulate":true}';
    var message =  eval( '(' + returnMessage + ')'); 
    var args = _args.split('|');
    for(var argidx=0; argidx < args.length; argidx++)
    {
      var idvalue = args[argidx].split('=');
      if(idvalue[0] == 'KGId')
        message.KGID = idvalue[1];
      if(idvalue[0] == 'KnowdeId')
        message.KnowdeID = idvalue[1];
      if(idvalue[0] == 'Repopulate' && idvalue[1].toLowerCase() == 'false')
        message.Repopulate = false;
        
    }
    HandleTextViewSaveComplete(message, m_Content);
  }
}

///////////////
// Saves the text view to the server
function SaveHKGroupTextView(_args)
{
  //if(m_EditFrame.contentWindow.document.body.innerHTML.toLowerCase().indexOf('images/clickedit') != -1)
    //m_EditFrame.contentWindow.document.body.innerHTML = '';   
  
  m_Content = m_EditFrame.contentWindow.document.body.innerHTML;
  
  SetTextViewToolbarSaving();
  
  var requiredSaving = 1;
  
  if(m_autoSaveTimeOut != null)
      clearTimeout(m_autoSaveTimeOut);
      
  if(_args != null && _args.indexOf('AutoSave') != -1)
  {
    requiredSaving = m_textViewChanged; //no changes made since last save
  }
  m_textViewChanged = 0;
  
  // get rid of tailing two line breaks that added in edit mode
  //if(m_Content.substr(m_Content.length - 10, 10) == '<br/><br/>')
    //m_Content = m_Content.substr(m_Content.length - 10, 10);

  // display the saving icon
  //m_EditFrame.contentWindow.document.body.innerHTML = "<div class='SavingMessage'><img src='Images/LoadingBar.gif'>&nbsp;Please wait while we save your changes...</div>";
  
  if(requiredSaving == 1)
  {
    // make the ajax call
    // default action
    var args = "Action=Save|";
    // if pass in specific action, use them instead
    if(_args != null && _args.length > 0)
      args = _args + "|";

    args += "Contents=" + m_Content;
      
    TextView_CallbackTrigger(args); 
  }
  else
  {
    // don't callback, just refresh the content
    var returnMessage = '{"Action":"AutoSave","OK":true,"Repopulate":true}';
    var message =  eval( '(' + returnMessage + ')'); 
    var args = _args.split('|');
    for(var argidx=0; argidx < args.length; argidx++)
    {
      var idvalue = args[argidx].split('=');
      if(idvalue[0] == 'Repopulate' && idvalue[1].toLowerCase() == 'false')
        message.Repopulate = false;
    }
    //HandleTextViewSaveComplete(message, m_Content);
  }
}

/////////////////////////////
// Inserts a link into the text view doument using the built in functionality
function TextViewInsertLink()
{
  if(m_EditFrame.contentWindow.document.designMode.toLowerCase() == "on")
  {
    var el = m_EditFrame.contentWindow;
    var selectedText = m_EditFrame.contentWindow.document.selection.createRange().text;
    // we are manually creating the link - so that we can force it to open in a new browser window.
    //formatTextLink();
    //EnsureTextViewPrompt();
    var url = prompt("Please enter the URL you want to insert.", "http://");
    // need to refocus because if user's browser block the script and user allow it, the focus will lost
    //m_EditFrame.contentWindow.focus(m_EditFrame.contentWindow.caretPos);
    if(url != null && url != "")
    {
			if (selectedText != "") 
			{
				var newText = "<a href='" + url + "' target='_blank'>" + selectedText + "</a>";//selectedText + "";
				el.document.selection.createRange().pasteHTML(newText);//text = newText;
			}
			else 
			{
				el.focus(el.caretPos);
				el.caretPos = document.selection.createRange().duplicate();
				if(el.caretPos.text.length == 0) 
				{
					el.caretPos.text = url + "";
				}
			}
		
      // ensure focus is in the text.
      m_EditFrame.contentWindow.focus(m_EditFrame.contentWindow.caretPos);
      TriggerAutoSave();
    }
  }
}

/* FUNCTION FOR ADDING AN A HREF TAG IN EDITOR */
function formatTextLink() 
{
  EnsureTextViewPrompt();
	/* IF INTERNET EXPLORER */
	if (window.showModalDialog) 
	{
		var myText = window.showModalDialog('chooseLinkUrl.html', 'name', 'dialogWidth:530px;dialogHeight:180px');
		var selectedText = document.selection.createRange().text;

		if (selectedText != "") 
		{
			var newText = myText + selectedText + "";
			document.selection.createRange().text = newText;
		}
		else 
		{
//			el.focus(el.caretPos);
//			el.caretPos = document.selection.createRange().duplicate();
//			if(el.caretPos.text.length == 0) 
//			{
//				el.caretPos.text = myText + "";
//			}
		}
	}
	/* IF MOZILLA */
	else 
	{
		window.open('chooseLinkUrl.html',
		'name',
		'height=180,width=530,toolbar=no,directories=no,status=no,menubar=no,scrollbars=no,resizable=no,modal=yes');
	}
}

var m_textViewHrefMessage;
///////////////////////
// Ensures that the delete message box is on the page
function EnsureTextViewPrompt()
{
   m_textViewHrefMessage = document.getElementById("HrefMessageBox");
  
  if(m_textViewHrefMessage == null)
  {
    m_textViewHrefMessage = document.createElement("div");
    m_textViewHrefMessage.setAttribute("id", "HrefMessageBox");
    m_textViewHrefMessage.style.display = "none";
    m_textViewHrefMessage.style.width = "530px"
    m_textViewHrefMessage.style.height = "180px";
//    m_textViewHrefMessage.style.position = "absolute";
    m_textViewHrefMessage.style.zIndex = TopZIndex();
    
		m_textViewHrefMessage.innerHTML += "<table>"
		m_textViewHrefMessage.innerHTML += "<tr><td colspan=\"3\"><h3>Specify link:</h3></td></tr>"
		m_textViewHrefMessage.innerHTML += "<tr>"
		m_textViewHrefMessage.innerHTML += "<td width=\"60\"><h4>Link:</h4></td>"
		m_textViewHrefMessage.innerHTML += "<td><input type=\"text\" value=\"http://\" id=\"linkUrl\" size=\"60\" /></td>"
		m_textViewHrefMessage.innerHTML += "<td><input type=\"button\" value=\"Paste\" onClick=\"returnSelected('linkUrl')\"></td>"
		m_textViewHrefMessage.innerHTML += "</tr>"
		m_textViewHrefMessage.innerHTML += "<tr>"
		m_textViewHrefMessage.innerHTML += "<td><h4>Open in:</h4></td>"
		m_textViewHrefMessage.innerHTML += "<td colspan=\"2\">"
		m_textViewHrefMessage.innerHTML += "<select id=\"trgt\">"
		m_textViewHrefMessage.innerHTML += "<option value=\"_top\">same window</option>"
		m_textViewHrefMessage.innerHTML += "<option value=\"_blank\">new window</option>"
		m_textViewHrefMessage.innerHTML += "</select>"
		m_textViewHrefMessage.innerHTML += "</td>"
		m_textViewHrefMessage.innerHTML += "</tr>"
		m_textViewHrefMessage.innerHTML += "</table>"
			
    
    document.body.appendChild(m_textViewHrefMessage);
  }
  else
  {
		m_textViewHrefMessage.innerHTML = "<br />"
		m_textViewHrefMessage.innerHTML += "<table>"
		m_textViewHrefMessage.innerHTML += "<tr><td colspan=\"3\"><h3>Specify link:</h3></td></tr>"
		m_textViewHrefMessage.innerHTML += "<tr>"
		m_textViewHrefMessage.innerHTML += "<td width=\"60\"><h4>Link:</h4></td>"
		m_textViewHrefMessage.innerHTML += "<td><input type=\"text\" value=\"http://\" id=\"linkUrl\" size=\"60\" /></td>"
		m_textViewHrefMessage.innerHTML += "<td><input type=\"button\" value=\"Paste\" onClick=\"returnSelected('linkUrl')\"></td>"
		m_textViewHrefMessage.innerHTML += "</tr>"
		m_textViewHrefMessage.innerHTML += "<tr>"
		m_textViewHrefMessage.innerHTML += "<td><h4>Open in:</h4></td>"
		m_textViewHrefMessage.innerHTML += "<td colspan=\"2\">"
		m_textViewHrefMessage.innerHTML += "<select id=\"trgt\">"
		m_textViewHrefMessage.innerHTML += "<option value=\"_top\">same window</option>"
		m_textViewHrefMessage.innerHTML += "<option value=\"_blank\">new window</option>"
		m_textViewHrefMessage.innerHTML += "</select>"
		m_textViewHrefMessage.innerHTML += "</td>"
		m_textViewHrefMessage.innerHTML += "</tr>"
		m_textViewHrefMessage.innerHTML += "</table>"
    m_textViewHrefMessage.style.zIndex = TopZIndex(); //Show on top of other items
  }
  
    m_textViewHrefMessage.style.display = "block";
  m_textViewHrefMessage.style.zIndex = TopZIndex();
  m_textViewHrefMessage.style.visibility = "visible";
//  focusOn("defaultButton");
//  CurrentlyShowingUosMessageBox = true;
}

//////////////////////////
// Kicks off the Insert image functionality by opening the upload window
function TextViewInsertImage()
{
//debugger;
  if(m_UploadWindow)
  {
    m_UploadWindow.close();
    if (window.KGTextViewEditingToolbar_UpdateUndoRedoBtns)
      // update the undoredo buttons
      KGTextViewEditingToolbar_UpdateUndoRedoBtns();
  }
    
  //m_UploadWindow = document.parentWindow.showModalDialog("TextViewUpload.aspx", null ,"dialogHeight:200px; dialogWidth:400px; status:No; center:Yes; scroll:No; help:No;");
  if (document.defaultView)
    m_UploadWindow = document.defaultView.open("TextViewUpload.aspx", "Upload" ,"height=200,width=400,status=no,toolbar=no,menubar=no,location=no,resizable=no,scrollbars=no,titlebar=no");
  else if (document.parentWindow)
    m_UploadWindow = document.parentWindow.open("TextViewUpload.aspx", "Upload" ,"height=200,width=400,status=no,toolbar=no,menubar=no,location=no,resizable=no,scrollbars=no,titlebar=no");
}

//////////////////////////
// Kicks off the insert file functionality by opening the upload window
function TextViewInsertFile()
{
  if(m_UploadWindow)
  {
    m_UploadWindow.close();
    if (window.KGTextViewEditingToolbar_UpdateUndoRedoBtns)
      // update the undoredo buttons
      KGTextViewEditingToolbar_UpdateUndoRedoBtns();
  }
  
  if (document.defaultView)
    m_UploadWindow = document.defaultView.open("TextViewFileUpload.aspx", "Upload" ,"height=200,width=400,status=no,toolbar=no,menubar=no,location=no,resizable=no,scrollbars=no,titlebar=no");
  else if (document.parentWindow)
    m_UploadWindow = document.parentWindow.open("TextViewFileUpload.aspx", "Upload" ,"height=200,width=400,status=no,toolbar=no,menubar=no,location=no,resizable=no,scrollbars=no,titlebar=no");
}


/////////////////////
// Completes the image upload process and inserts the given url at the current location
// _url: The full url of the image to be inserted
function CompleteImageUpload(_url)
{
  //debugger;
  // if the upload window is active then close it
  if(m_UploadWindow)
    m_UploadWindow.close();
 
  //TS: Bug 2868 fix - ensure focus is in the text.
  m_EditFrame.contentWindow.focus();
  
  // insert the image into the document
  if(m_EditFrame.contentWindow.document.designMode.toLowerCase() == "on")
  {
    m_EditFrame.contentWindow.document.execCommand("InsertImage", false, _url);
    TriggerAutoSave();
    setTimeout("AdjustEditFrameSize()", 400);
  }
}

/////////////////////
// Completes the file upload process and inserts the given url at the current location
// _url: The full url of the file to be inserted
function CompleteFileUpload(_url)
{
  // if the upload window is active then close it
  if(m_UploadWindow)
    m_UploadWindow.close();
  
  // insert the file into the document
  if(m_EditFrame.contentWindow.document.designMode.toLowerCase() == "on")
  {
    var dotIndex = _url.lastIndexOf(".");
    if(dotIndex <=0 )
      return;
    
    var extension = _url.substr(dotIndex, (_url.length - dotIndex));
    var imgUrl = "Images/FileTypes/Unknown.png";
  
      // if the file is of a known type then use that image instead
    switch(extension)
    {
        // MS word
        case ".doc":
        case ".docx":
          imgUrl = "Images/FileTypes/Word.png";
          break;
        // MS Excel
        case ".xls":
        case ".xlsx":
          imgUrl = "Images/FileTypes/Excel.png";
          break;
         // MS Powerpoint
        case ".ppt":
        case ".pps":
        case ".pptx":
          imgUrl = "Images/FileTypes/PowerPoint.png";
          break;
         // Adobe PDF
        case ".pdf":
          imgUrl = "Images/FileTypes/PDF.png";
          break;
        // Plain Text
        case ".txt":
          imgUrl = "Images/FileTypes/Text.png";
          break;
        // MS Visio
        case ".vsd":
          imgUrl = "Images/FileTypes/Visio.png";
          break;
        // All image formats
        case ".png":
        case ".gif":
        case ".jpg":
        case ".jpeg":
        case ".jpe":
        case ".bmp":
        case ".psd":
        case ".psp":
        case ".raw":
        case ".tif":
        case ".tiff":
          imgUrl = "Images/FileTypes/Image.png";
          break;
        // All mail messages
        case ".eml":
        case ".msg":
          imgUrl = "Images/FileTypes/Mail.png";
          break;
        // All Compressed formats
        case ".zip":
        case ".arj":
        case ".cab":
        case ".gz":
        case ".rar":
        case ".tar":
        case ".zoo":
          imgUrl = "Images/FileTypes/Zip.png";
          break;
    }

    // insert the correct html into the document. instead of doing this using execCommand we have to insterst it using a range
    
    // first make sure the selection corresponds to the text view window (it doesn't if you haven't clicked it yet)
    m_EditFrame.contentWindow.focus(); 
    InsertHtmlToIframe("<a href='" + _url + "' target='_blank'><img border='0' src='" + imgUrl + "'/>&nbsp;Link</a>");
    TriggerAutoSave();
    
    setTimeout("AdjustEditFrameSize()", 400);
  }
}

function GetRangeObject(selectionObject) {
	if (selectionObject.getRangeAt)
		return selectionObject.getRangeAt(0);
	else { // Safari!
		var range = document.createRange();
		range.setStart(selectionObject.anchorNode,selectionObject.anchorOffset);
		range.setEnd(selectionObject.focusNode,selectionObject.focusOffset);
		return range;
	}
}

function InsertHtmlToIframe(_newHtml)
{
  var range;
  if (m_EditFrame.contentWindow.getSelection)   // make the range be in the iframe explicitly for ff
    range = GetRangeObject(m_EditFrame.contentWindow.getSelection());
  else if (document.selection) //already focussed on the iframe
    range = document.selection.createRange();

  range.collapse(false); // collapse makes the start and end position of the range the same place

  if (range.pasteHTML)
    range.pasteHTML(_newHtml);
  else
  {
    var newEl = m_EditFrame.contentWindow.document.createElement('div');
    newEl.innerHTML = _newHtml;
    range.insertNode(newEl.firstChild);
  }
}   

//////////////////////////
// Called when the mouse floats over a toolbar button, making it highlighted
// _button: the button floated over
function TextViewButtonOver(_button)
{
  _button.className = "TextViewToolbarButtonOver";
}

//////////////////////////
// Called when the mouse floats out of toolbar button, removing the highlight
// _button: the button floated over
function TextViewButtonOut(_button)
{
  _button.className = "TextViewToolbarButton";
}

////////////////////
// Calls the built in Ordered List functionality
function TextViewOList()
{
  if(m_EditFrame.contentWindow.document.designMode.toLowerCase() == "on")
  {
    m_EditFrame.contentWindow.document.execCommand('InsertOrderedList', false, null);
    
    TriggerAutoSave();
    
    //TS: Bug 3810 fix - ensure focus is in the text.
    m_EditFrame.contentWindow.focus();
  }
}

////////////////////
// Calls the built in Unordered List functionality
function TextViewUList()
{
  if(m_EditFrame.contentWindow.document.designMode.toLowerCase() == "on")
  {
    m_EditFrame.contentWindow.document.execCommand('InsertUnorderedList', false, null);
    
    TriggerAutoSave();
    
    //TS: Bug 3810 fix - ensure focus is in the text.
    m_EditFrame.contentWindow.focus();
  }
}

////////////////////
// Calls the built in bold functionality
function TextViewBold()
{
  if(m_EditFrame.contentWindow.document.designMode.toLowerCase() == "on")
  {
    m_EditFrame.contentWindow.document.execCommand("Bold", false, null);
    
    TriggerAutoSave();
    
    //TS: Bug 3810 fix - ensure focus is in the text.
    m_EditFrame.contentWindow.focus();
  }
}

////////////////////
// Calls the built in italic functionality
function TextViewItalic()
{
  if(m_EditFrame.contentWindow.document.designMode.toLowerCase() == "on")
  {
    m_EditFrame.contentWindow.document.execCommand("Italic", false, null);
    
    TriggerAutoSave();
    
    //TS: Bug 3810 fix - ensure focus is in the text.
    m_EditFrame.contentWindow.focus();
  }
}

////////////////////
// Calls the built in underline functionality
function TextViewUnderline()
{
  if(m_EditFrame.contentWindow.document.designMode.toLowerCase() == "on")
  {
    m_EditFrame.contentWindow.document.execCommand("Underline", false, null);
    
    TriggerAutoSave();
    
    //TS: Bug 3810 fix - ensure focus is in the text.
    m_EditFrame.contentWindow.focus();
  }
}

////////////////////
// Calls the built in increase indent functionality
function TextViewIncIndent()
{
  if(m_EditFrame.contentWindow.document.designMode.toLowerCase() == "on")
  {
    m_EditFrame.contentWindow.document.execCommand("Indent", false, null);
    //if (m_textViewMode == 'HKGROUPDOC')
      //m_EditFrame.style.height = m_EditFrame.contentWindow.document.body.scrollHeight + m_editFrameHeightMargin + 'px';
    
    TriggerAutoSave();
    
    //TS: Bug 3810 fix - ensure focus is in the text.
    m_EditFrame.contentWindow.focus();
 }
}

////////////////////
// Calls the built in decrease indent functionality
function TextViewDecIndent()
{
  if(m_EditFrame.contentWindow.document.designMode.toLowerCase() == "on")
  {
    m_EditFrame.contentWindow.document.execCommand("Outdent", false, null);
    //if (m_textViewMode == 'HKGROUPDOC')
//      m_EditFrame.style.height = m_EditFrame.contentWindow.document.body.scrollHeight + m_editFrameHeightMargin + 'px';
    
    TriggerAutoSave();
    
    //TS: Bug 3810 fix - ensure focus is in the text.
    m_EditFrame.contentWindow.focus();
  }
}

////////////////////
// Called when the style drop list in the toolbar has it's selectiopn changed
function TextViewStyleChanges(_styleDropList)
{
  formatBlock(_styleDropList.value);
}

////////////////////
// Formats the current element with the supplied tag
// _tag: the html element to use fot the formatting
function formatBlock(_tag)
{
  if(m_EditFrame.contentWindow.document.designMode.toLowerCase() == "on")
  {
    m_EditFrame.contentWindow.document.execCommand("formatblock", false, "<" + _tag + ">");
    //if (m_textViewMode == 'HKGROUPDOC')
//     m_EditFrame.style.height = m_EditFrame.contentWindow.document.body.scrollHeight + m_editFrameHeightMargin + 'px';
   
    TriggerAutoSave(); 
  }
}

////////////////
// Calls the built in cut functionality
function TextViewCut()
{
  if(m_EditFrame.contentWindow.document.designMode.toLowerCase() == "on"  && navigator.appName == "Microsoft Internet Explorer")
  {
    m_EditFrame.contentWindow.document.execCommand("Cut", false, null);
    //if (m_textViewMode == 'HKGROUPDOC')
//      m_EditFrame.style.height = m_EditFrame.contentWindow.document.body.scrollHeight + m_editFrameHeightMargin + 'px';
    
    TriggerAutoSave();
    return true;
  }
  else
  {
    return false;
  }
}

////////////////
// Calls the built in copy functionality
function TextViewCopy()
{
  if(m_EditFrame.contentWindow.document.designMode.toLowerCase() == "on" && navigator.appName == "Microsoft Internet Explorer")
  {
    m_EditFrame.contentWindow.document.execCommand("Copy", false, null);
    return true;
  }
  else
    return false;
}

////////////////
// Calls the built in paste functionality
function TextViewPaste()
{
  if(m_EditFrame.contentWindow.document.designMode.toLowerCase() == "on" && navigator.appName == "Microsoft Internet Explorer")
  {
    m_EditFrame.contentWindow.document.execCommand("Paste", false, null);
    //if (m_textViewMode == 'HKGROUPDOC')
//      m_EditFrame.style.height = m_EditFrame.contentWindow.document.body.scrollHeight + m_editFrameHeightMargin + 'px';
    
    TriggerAutoSave();
    return true;
  }
  else
    return false;
}

////////////////
// Calls the built in undo functionality
function TextViewUndo()
{
  if(m_EditFrame.contentWindow.document.designMode.toLowerCase() == "on")
  {
    m_EditFrame.contentWindow.document.execCommand("Undo", false, null);
    //if (m_textViewMode == 'HKGROUPDOC')
//      m_EditFrame.style.height = m_EditFrame.contentWindow.document.body.scrollHeight + m_editFrameHeightMargin + 'px';
  
    TriggerAutoSave();
  }
}

////////////////
// Calls the built in redo functionality
function TextViewRedo()
{
  if(m_EditFrame.contentWindow.document.designMode.toLowerCase() == "on")
  {
    m_EditFrame.contentWindow.document.execCommand("Redo", false, null);
    //if (m_textViewMode == 'HKGROUPDOC')
//      m_EditFrame.style.height = m_EditFrame.contentWindow.document.body.scrollHeight + m_editFrameHeightMargin + 'px';
    
    TriggerAutoSave();
  }
}


var tickerSpanStartTag = '<span id="ticker" style="background-color:transparent;">';
var tickerSpanEndTag = '</span>';
var tickerSelection;
var tickerSelection0;
var tickerSelection1;
var tickerSelection2;

var tickerSelectionText;
var tickerSelectionTextArray = new Array();

var tickerSelectionPattern;
var tickerSelectionPatternArray = new Array();

function removeHTMLTags(_input){
		var strInputCode = _input;
		/* 
			This line is optional, it replaces escaped brackets with real ones, 
			i.e. &lt; is replaced with < and &gt; is replaced with >
		*/	
		/*strInputCode = strInputCode.replace(/&(lt|gt);/g, function (strMatch, p1){
			return (p1 == "lt")? "<" : ">";
		});*/
		var strTagStrippedText = strInputCode.replace(/<\/?[^>]+(>|$)/g, "");
		return strTagStrippedText;
}

function removeLineBreaks(_input, _replaceText)
{
    if(_replaceText == null)
      _replaceText = '';
    var input = _input;
    var lineBreakIdx = input.indexOf('\u000A');
    while(lineBreakIdx > 0)
    {
      input = input.substr(0, lineBreakIdx-1) + _replaceText + input.substr(lineBreakIdx+1);
      lineBreakIdx = input.indexOf('\u000A');
    }
    input = input.replace(new RegExp("\\r\\n","m"),_replaceText);
    input = input.replace(new RegExp("\\r","m"),_replaceText);
    input = input.replace(new RegExp("\\n","m"),_replaceText);
    
    return input;
}

// This has to be done in a separate function, as otherwise clicking the button removes the selection
function copySelection()
{
  tickerSelectionTextArray = new Array();
  
  if (m_EditFrame.contentWindow.getSelection) // non-IE
  {
  	var rng = GetRangeObject(m_EditFrame.contentWindow.getSelection());
  	tickerSelectionText = rng.toString();
  	var clonedSelection = rng.cloneContents();
    var newEl = document.createElement('div');
    newEl.appendChild(clonedSelection);
    tickerSelection = newEl.innerHTML;
  }
  else if (m_EditFrame.contentWindow.document.selection) // IE
  {
	  var rng = m_EditFrame.contentWindow.document.selection.createRange();
	  tickerSelectionText = rng.text;
	  tickerSelection = rng.htmlText;
	}
	    
  if(tickerSelection != null)
  {
    // trim out ticker spans in the original selection text
    var sel = TrimTickerSpans(tickerSelection);
    tickerSelection0 = sel;
    var rnIdx = -1;
    // trim leading and tailing tags
    /*rnIdx = sel.indexOf('\u000A');
    while(rnIdx >= 0)
    {
      sel = sel.substr(0, rnIdx-1) + '[@HK_LineBreak@]' + sel.substr(rnIdx);
      rnIdx = sel.indexOf('\u000A', rnIdx+1+16);
    }
    rnIdx = sel.indexOf('</');
    while(rnIdx >= 0)
    {
      sel = sel.substr(0, rnIdx-1) + '[@HK_LineBreak@]' + sel.substr(rnIdx);
      rnIdx = sel.indexOf('</', rnIdx+2+16);
    }*/
    rnIdx = sel.indexOf('<');
    while(rnIdx >= 0)
    {
      sel = sel.substr(0, rnIdx) + '[@HK_LineBreak@]' + sel.substr(rnIdx);
      rnIdx = sel.indexOf('<', rnIdx+1+16);
    }
    
    tickerSelectionTextArray = sel.split("[@HK_LineBreak@]");
    if(tickerSelectionTextArray.length > 0)
    {
      tickerSelection0 = '';
      tickerSelectionPattern = '';
      for(var ti = 0; ti < tickerSelectionTextArray.length; ti++)
      {
        tickerSelectionTextArray[ti] = removeHTMLTags(tickerSelectionTextArray[ti]);
        var actualText = removeLineBreaks(tickerSelectionTextArray[ti]);
        if(actualText.length > 0)
          break;
      }
      for(var ti2 = tickerSelectionTextArray.length-1; ti2 >= 0; ti2--)
      {
        var trimedText = removeHTMLTags(tickerSelectionTextArray[ti2]);
        var actualText = removeLineBreaks(trimedText);
        if(actualText.length > 0)
          break;
        else
          tickerSelectionTextArray[ti2] = trimedText;
      }
      //tickerSelectionPatternArray = new Array(tickerSelectionTextArray.length);
      for(var ti3 = 0; ti3 < tickerSelectionTextArray.length; ti3++)
      {
        var actualText = removeLineBreaks(tickerSelectionTextArray[ti3]);
        if(actualText.length > 0){
          tickerSelection0 = tickerSelection0 + tickerSelectionTextArray[ti3];
          //var pattenText = removeLineBreaks(tickerSelectionTextArray[ti3], ').*(');
          //if(tickerSelectionPattern.length > 0)
            //tickerSelectionPattern = tickerSelectionPattern + '.*';
          //tickerSelectionPattern = tickerSelectionPattern + '(' + pattenText.replace(' )',')').replace('( ','(') + ')';
          //tickerSelectionPatternArray[ti3] = pattenText.replace(' )',')').replace('( ','(');
        }//else
          //tickerSelectionPatternArray[ti3] = '';
      }
      //if(tickerSelectionPattern.length > 0)
      //{
        //tickerSelectionPattern = '(' + tickerSelectionPattern + ')';
      //}
    }

    
    // the html text could be multiline format, so filter the line breaks
    //tickerSelection1 = tickerSelection.replace(new RegExp("\\u000A","m"),''); // not working, tickerSelection.replace(/u000A/m,'');  or tickerSelection.replace(/\u000A/m,''); not working as well
    tickerSelection1 = tickerSelection0;
    var lineBreakIdx = tickerSelection1.indexOf('\u000A');
    while(lineBreakIdx > 0)
    {
      tickerSelection1 = tickerSelection1.substr(0, lineBreakIdx-1) + tickerSelection1.substr(lineBreakIdx+1);
      lineBreakIdx = tickerSelection1.indexOf('\u000A');
    }
    // filter out \r\n as well
    tickerSelection2 = tickerSelection1.replace(new RegExp("\\r\\n","m"),'');
    tickerSelection2 = tickerSelection2.replace(new RegExp("\\r","m"),'');
    tickerSelection2 = tickerSelection2.replace(new RegExp("\\n","m"),'');
  }
}

function TrimTickerSpans(_contents)
{
    //debugger;
    var contents = _contents;
    
    var tickerPos = -1; //contents.search(/(ticker)/i);//contents.toLowerCase().indexOf('ticker', 0);
    var tickerPosRe = new RegExp('(ticker)', 'gi');
    var tickerPosMatch = tickerPosRe.exec(contents);
    if(tickerPosMatch != null)
      tickerPos = tickerPosMatch.index;
    while(tickerPos > 0)
    {
      // check whether it's a span tag
      var tagStr = '';
      var wIdx = tickerPos -1;
      while(wIdx >= 0)
      {
        var wchar = contents.substr(wIdx, 1);
        if(wchar == '<' || wchar == '>')
        {
          tagStr = wchar + tagStr;
          if(wchar == '<')
            tagStartPosition = wIdx;
          break;
        }
        else if(wchar != '"' && wchar != "'" && wchar != '\u000A' && wchar != '\r' && wchar != '\n')
        {
          tagStr = wchar + tagStr;
        }
        wIdx--;
      }
      // trim out ticker span if exists
      if(tagStr.toLowerCase().indexOf('<span') == 0 && tagStr.toLowerCase().indexOf('id=') + 2 == tagStr.length -1 && tagStartPosition >= 0)
      {
        var text = contents.substring(tagStartPosition);
        var textStartPosition = text.search(/>/) + tagStartPosition + 1;
        var endPosition = -1;
        // Check position of next span tag
        var text2 = text.substr(textStartPosition - tagStartPosition);
        var re = new RegExp('(<span([^>]*)>)', 'gi');
        var re2 = new RegExp('(<\/span>)', 'gi');
        var matchResult = re.exec(text2);
        var matchResult2 = re2.exec(text2);
        while(matchResult != null && matchResult2 != null)
        {
          if(matchResult[0].indexOf('/>') != -1)
            matchResult = re.exec(text2); // skip this close tag
          else
          {
            if(matchResult.index < matchResult2.index) // there is embeded span tag
            {
              matchResult = re.exec(text2);
              matchResult2 = re2.exec(text2);
            }else
            {
              break;
            }
          }
        }
        if( matchResult2 != null)
          endPosition = matchResult2.index + textStartPosition;
        
        if(endPosition == -1)
          endPosition = text.search(/<\/span>/i) + tagStartPosition;
        
        if(endPosition == -1)
        {
          // no end tag found
          endPosition = textStartPosition-7;
        }
        var tickerText = contents.substring(textStartPosition,endPosition);

        // 2. Replace the whole tagged section with the value between the tags.
        var startText = contents.substring(0,tagStartPosition);
        var endText = contents.substring(endPosition+7);
        //if (startText != "" && endText != "") 
        contents = startText + tickerText + endText;
        
        tagStartPosition = -1;
      }
        
      //tickerPos = contents.search(/(ticker)/i); //contents.toLowerCase().indexOf('ticker', tickerPos);
      tickerPos = -1;
      tickerPosMatch = tickerPosRe.exec(contents);
      if(tickerPosMatch != null)
        tickerPos = tickerPosMatch.index;
    }
    return contents;
}

////////////////
// Puts tags round the selected text to indicate that it is to be used in the ticker
function TextViewSetTickerText() //JPC, XD updated to support cross tags selection
{ 
  // debugger; 
  // NB it will probably be necessary to look for an alternative to document.selection for Mozilla
  if(m_EditFrame.contentWindow.document.designMode.toLowerCase() == "on")
  {
    // If we're in edit mode, only the text for the current knowde is shown, so we don't have to worry about finding it.
    // Strip out any existing tags
    // 1. Find the value between the tags
    var originalContents = TrimTickerSpans(m_EditFrame.contentWindow.document.body.innerHTML);
    if(originalContents.length > 0)
      m_EditFrame.contentWindow.document.body.innerHTML = originalContents;

    var htmlUpdated = 0;
    
    var button = document.getElementById("KGButtonToolbar_ShowTicker");
    button.className = "ButtonToolbar_TextButtonDivInactive";
    
    // Put tags round the selection
    if (tickerSelection != "" && tickerSelection1 != "" && tickerSelection2 != "")
    {
      if(tickerSelection.indexOf('<') == -1 && m_EditFrame.contentWindow.document.body.innerHTML.indexOf(tickerSelection) != -1)
      {
        var newText = tickerSpanStartTag + tickerSelection + tickerSpanEndTag;
        m_EditFrame.contentWindow.document.body.innerHTML = m_EditFrame.contentWindow.document.body.innerHTML.replace(tickerSelection,newText);
        htmlUpdated = 1;
      }
      else if(tickerSelection1.indexOf('<') == -1 && m_EditFrame.contentWindow.document.body.innerHTML.indexOf(tickerSelection1) != -1)
      {
        var newText = tickerSpanStartTag + tickerSelection1 + tickerSpanEndTag;
        m_EditFrame.contentWindow.document.body.innerHTML = m_EditFrame.contentWindow.document.body.innerHTML.replace(tickerSelection1,newText);
        htmlUpdated = 1;
      }
      else if(tickerSelection2.indexOf('<') == -1 && m_EditFrame.contentWindow.document.body.innerHTML.indexOf(tickerSelection2) != -1)
      {
        var newText = tickerSpanStartTag + tickerSelection2 + tickerSpanEndTag;
        m_EditFrame.contentWindow.document.body.innerHTML = m_EditFrame.contentWindow.document.body.innerHTML.replace(tickerSelection2,newText);
        htmlUpdated = 1;
      }else if (tickerSelectionTextArray.length > 0 && tickerSelection2.length > 0)
      {
        // use regx
        tickerSelectionPatternArray = new Array(tickerSelectionTextArray.length);
        for(var ti3 = 0; ti3 < tickerSelectionTextArray.length; ti3++)
        {
          var actualText = removeHTMLTags(tickerSelectionTextArray[ti3]);
          actualTextNoLineBreaks = removeLineBreaks(actualText, '');;
          if(actualTextNoLineBreaks.length > 0){
            var pattenText = removeLineBreaks(tickerSelectionTextArray[ti3], ').*(');
            pattenText = '(' + pattenText + ')';
            tickerSelectionPatternArray[ti3] = pattenText.replace(' )',')').replace('( ','(');
          }else
            tickerSelectionPatternArray[ti3] = '';
        }
        
        var previousEndIdx = 0;
        var previousStartIdx = 0;
        var contentHtml = m_EditFrame.contentWindow.document.body.innerHTML;
        
        for(var ti4 = 0; ti4 < tickerSelectionPatternArray.length; ti4++)
        {
          if(tickerSelectionPatternArray[ti4].length > 0)
          {
            pattern = tickerSelectionPatternArray[ti4];
            var re = new RegExp(pattern, 'g');
            var matchResult = re.exec(contentHtml);
            
            while(matchResult != null)
            {
              var startIdx = matchResult.index;
              var endIdx = startIdx;
              var tickerText = '';
              var appendTickerText = 1; // currently always would be 1
              var inTags = 0;
              var startNewTickerSpan = 1;
              var endNewTickerSpan = 0;
              
              // compare selection
              var currentIdx = startIdx;
              var currentSelIdx = 0;
              var matched = 1;
              // note, regularexpression to match the whole selection is not always working due to certain line breaks and unwanted auto generated tags
              while(currentIdx < contentHtml.length && currentSelIdx < tickerSelection2.length)
              {
                var c1 = contentHtml.substr(currentIdx,1);
                var c2 = tickerSelection2.substr(currentSelIdx,1); // tickerSelection2 has no line break
                if(c1 == '\u000A' || c1 == '\r' || c1 == '\n')
                {
                  currentIdx++;
                  if(appendTickerText == 1 && inTags == 0 && startNewTickerSpan == 0 && tickerText.length > 0)
                    {
                      /* // don't include line breaks in span tag, otherwise the format could be wrong
                      if(startNewTickerSpan == 1)
                      {
                        tickerText = tickerText + tickerSpanStartTag;
                        startNewTickerSpan = 0;
                      }*/
                      tickerText = tickerText + c1;
                      endNewTickerSpan = 1;
                  }
                }
                else if(c1.toLowerCase() == c2.toLowerCase())
                {
                  currentIdx++;
                  currentSelIdx++;
                  if(c1 != '<' && c1 != '>')
                  {
                    if(appendTickerText == 1)
                    {
                      var changeSpace = 0;
                      // don't include leading white spaces in span tag, otherwise the format could be wrong
                      if(startNewTickerSpan == 1 && inTags == 0)
                      {
                        tickerText = tickerText + tickerSpanStartTag;
                        startNewTickerSpan = 0;
                        endNewTickerSpan = 1;
                        if(c1 == ' ')
                          changeSpace = 1;
                      }
                      if(changeSpace == 0)
                        tickerText = tickerText + c1;
                      else
                        tickerText = tickerText + '&nbsp;';
                    }
                  }else if(c1 == '<')
                  {
                    inTags = 1;
                    if(tickerText.length > 0 && endNewTickerSpan == 1)
                    {
                      var spaceStr = '';
                      // don't include tailing white spaces in the span tag otherwise the format could be wrong
                      for(var sIdx = tickerText.length-1; sIdx >= 0; sIdx--)
                      {
                        if(tickerText.substr(sIdx,1) != ' ')
                        {
                          // non space character
                          tickerText = tickerText.substr(0, sIdx + 1) + spaceStr + tickerSpanEndTag;
                          
                          break;
                        }else
                        {
                          spaceStr = spaceStr + '&nbsp;';
                        }
                      }
                      
                      endNewTickerSpan = 0;
                    }
                    if(appendTickerText == 1)
                    {
                      tickerText = tickerText + c1;
                    }
                  }else if(c1 == '>')
                  {
                    if(inTags == 1)
                    {
                      inTags = 0;
                      startNewTickerSpan = 1;
                    }
                    if(appendTickerText == 1)
                    {
                      tickerText = tickerText + c1;
                    }
                  }
                  
                }else
                {
                  // due to the space sometimes not come out correctly inside the ticker span, so we replace it with &nbsp; instead
                  // and the selection sometimes not contain this one
                  if(c1 == '&' && contentHtml.substr(currentIdx,6) == '&nbsp;')
                  {
                    currentIdx = currentIdx + 6;
                    if(startNewTickerSpan == 1 && inTags == 0)
                    {
                        tickerText = tickerText + tickerSpanStartTag;
                        startNewTickerSpan = 0;
                        endNewTickerSpan = 1;
                    }
                    tickerText = tickerText + '&nbsp;';
                    if(c2 == ' ') // if it's matching space, then skip as well
                      currentSelIdx++;
                  }
                  // the document.selection.CreateRange().htmlText might auto add a </SPAN> tag somewhere
                  else if(tickerSelection2.substr(currentSelIdx-2,2) == '</')
                  {
                    var closeIdx = tickerSelection2.indexOf('>', currentSelIdx);
                    if(closeIdx >= currentSelIdx)
                    {
                      currentSelIdx = closeIdx + 1;
                      currentIdx = currentIdx - 2; // already walk </ in contentHTML
                      tickerText = tickerText.substr(0,tickerText.length-2);
                    }
                    else
                    {
                      matched = 0; // not mached
                      break;
                    }
                      
                  }
                  else if(tickerSelection2.substr(currentSelIdx-1,2) == '</')
                  {
                    var closeIdx = tickerSelection2.indexOf('>', currentSelIdx);
                    if(closeIdx >= currentSelIdx)
                    {
                      currentSelIdx = closeIdx + 1;
                      currentIdx = currentIdx - 1; // already walk < in contentHTML
                      tickerText = tickerText.substr(0,tickerText.length-1);
                    }
                    else
                    {
                      matched = 0; // not mached
                      break;
                    }
                      
                  }
                  else if(tickerSelection2.substr(currentSelIdx,2) == '</')
                  {
                    var closeIdx = tickerSelection2.indexOf('>', currentSelIdx);
                    if(closeIdx >= currentSelIdx)
                    {
                      currentSelIdx = closeIdx + 1;
                    }
                    else
                    {
                      matched = 0; // not mached
                      break;
                    }
                      
                  }
                  else if(c1 == ' ' && c2 != ' ' && inTags == 0)
                  {
                    if(tickerSelection2.substr(currentSelIdx-1,1) == ' ' || tickerSelection2.substr(currentSelIdx-1,1) == '>' || tickerSelection2.substr(currentSelIdx,1) == '<')
                    {
                      currentIdx++;
                      if(startNewTickerSpan == 1 && inTags == 0)
                      {
                        tickerText = tickerText + tickerSpanStartTag;
                        startNewTickerSpan = 0;
                        endNewTickerSpan = 1;
                        if(c1 == ' ')
                          changeSpace = 1;
                      }
                      if(changeSpace == 0)
                        tickerText = tickerText + c1;
                      else
                        tickerText = tickerText + '&nbsp;';
                      
                    }else
                    {
                      matched = 0; // not mached
                      break;
                    }
                  }
                  else
                  {
                    matched = 0; // not mached
                    break;
                  }
                }
              }
              if(matched == 1 && currentIdx == contentHtml.length && currentSelIdx < tickerSelection2.length )
                matched = 0; // reach the end of the iframe html, but the search text is not reach the end yet, so no match
              if(matched == 1 && currentIdx >  startIdx)
              {
                endIdx = currentIdx;
                if(tickerText.length > 0)
                {
                  if(endNewTickerSpan == 1)
                      tickerText = tickerText + tickerSpanEndTag;// insert ticker span
                   m_EditFrame.contentWindow.document.body.innerHTML = contentHtml.substr(0,startIdx) + tickerText + contentHtml.substr(endIdx);
                   htmlUpdated = 1;
                }
                
                break;
              }
              else
                matchResult = re.exec(contentHtml); // search next
            }
            //contentHtml = contentHtml.substr(previousEndIdx+1);
            break;
          } // end if;
        }
      }
            
      // Set 'Show ticker text' to active
			if(Active_KGID == globalHelpID)
			{
				button.className = "ButtonToolbar_TextButtonDivActive";
			}
    }
    
    if(htmlUpdated == 1)
      TriggerAutoSave();
  }
}

////////////////
// Highlight the text for the current knowde that has ticker tags around it
// adapted from SetupKnowdeTextViewDiv()
function TextViewShowTickerText() //JPC
{
  //debugger;
  var editFrame = document.getElementById("TextViewEditFrame-k"+m_strSelectedKnowdeID);
  if(editFrame != null)
  {    
    var tickerSpan = null;
    // we need to create a function to test against. If the function returns true when an element 
    // is passed into it then that element is added to the array that is returned.
    var method = function(el){if(el.id == "ticker") return true; return false;};
    var results = YAHOO.util.Dom.getElementsBy(method,null,editFrame.contentWindow.document.body);
    if(results.length > 0) //A knowde can only have 1 ticker selection
    {
      var firstOne = 1;
      for(var r = 0; r < results.length; r++)
      {
        tickerSpan = results[r];
        
        if (tickerSpan != null)
        {
          tickerSpan.style.backgroundColor = m_textViewTickerSelectionHighlightColor;
          
          if(firstOne == 1)
          {
            // Set 'Show ticker text' to inactive
            var button = document.getElementById("KGButtonToolbar_ShowTicker");
            button.className = "ButtonToolbar_TextButtonDivInactive";  
          
            // auto scroll to the position
            if(m_EditFrameDiv == null)
              m_EditFrameDiv = document.getElementById('TextViewEditFrameDiv');
            if(m_EditFrameDiv != null && editFrame.offsetTop >= 0)
             m_EditFrameDiv.scrollTop  = editFrame.offsetTop;
             
             firstOne = 0;
          }
        }
      }
    }
  
    
  }
}

////////////////
// Unhighlight the text for the current knowde that has ticker tags around it
// See also ReturnUnhighlightedTickerText
function TextViewUnhighlightTickerText() //JPC
{
  var editFrame = document.getElementById("TextViewEditFrame-k"+m_strSelectedKnowdeID);
  if(editFrame != null)
  {    
    var tickerSpan = null;
    // we need to create a function to test against. If the function returns true when an element 
    // is passed into it then that element is added to the array that is returned.
    var method = function(el){if(el.id == "ticker") return true; return false;};
    var results = YAHOO.util.Dom.getElementsBy(method,null,editFrame.contentWindow.document.body);
    if(results.length == 1) //A knowde can only have 1 ticker selection
    {
      tickerSpan = results[0];
    }
  
    if (tickerSpan != null)
    {
      tickerSpan.style.backgroundColor = 'transparent';
      // Set 'Show ticker text' to active
      if(Active_KGID == globalHelpID)
			{
				var button = document.getElementById("KGButtonToolbar_ShowTicker");
				button.className = "ButtonToolbar_TextButtonDivActive";
      }
    }
  }
}

// Return unhighlighted text view text given _content
// Based on TextViewUnhighlightTickerText
function ReturnUnhighlightedTickerText(_content) 
{
  var tempEl = document.createElement("div")
  tempEl.innerHTML = _content;
  var tickerSpan = null;
  // we need to create a function to test against. If the function returns true when an element 
  // is passed into it then that element is added to the array that is returned.
  var method = function(el){if(el.id == "ticker") return true; return false;};
  var results = YAHOO.util.Dom.getElementsBy(method,null,tempEl);
  if(results.length == 1) //A knowde can only have 1 ticker selection
  {
    tickerSpan = results[0];
  }

  if (tickerSpan != null)
  {
    tickerSpan.style.backgroundColor = 'transparent';
  }
  return tempEl.innerHTML;
}


////////////////
// Adds in some standard text to the text view so it's easier to test
function TextViewDebugText()
{
  m_EditFrame.contentWindow.document.write("<h1>The quick brown fox jumps over the lazy dog.</h1> <p>The quick brown fox jumps over the lazy dog.  The quick brown fox jumps over the lazy dog.  The quick brown fox jumps over the lazy dog.  The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog.  The quick brown fox jumps over the lazy dog.  The quick brown fox jumps over the lazy dog.  The quick brown fox jumps over the lazy dog.  The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog.  The quick brown fox jumps over the lazy dog.  The quick brown fox jumps over the lazy dog.  The quick brown fox jumps over the lazy dog.  The quick brown fox jumps over the lazy dog.</p>");
}

function TextViewControl_DisplayCompass( _linkItem )
{
  // get the compass from the page
  var compass = document.getElementById( 'textviewCompass' );
  
  // only do something if the compass is a valid object
  if( typeof(compass) == "object" )
  {
    // set the children on the compass
    // TODO: are childId's actually needed?    
    var compassItem = document.getElementById("TextViewCompassWhy");
    if( compassItem != null && typeof(compass) == "object" )
    {
      compassItem.childId = _linkItem.whyChild;
      compassItem.knowdeId = _linkItem.knowdeId;  
    }
    
    var compassItem = document.getElementById("TextViewCompassHow");
    if( compassItem != null && typeof(compass) == "object" )
    {
      compassItem.childId = _linkItem.howChild;
      compassItem.knowdeId = _linkItem.knowdeId;    
    }
    
    compass.directions = _linkItem.directions;
    compass.cascadeItem = _linkItem;
    compass.hasVisibleChild = false;
    compass.visibleChild = null;
    
    // set the compass directions, making sure that there is something to set first
    // TODO: could we actually do compass.childNodes[1].childNodes[0].style.... instead? - less code and no document.getElementById?
    // How direction
    var howArrow = document.getElementById("TextViewCompassHow");
    if( typeof( howArrow ) == "object" )
    {
      if( compass.directions & 1 ) 
      {
        howArrow.childNodes[0].src = CompassHowOn.src;
        howArrow.attachEvent( "onclick", TextViewControl_displayHows );
      }
		  else
		  {
		    howArrow.childNodes[0].src = CompassHowOff.src;
		    howArrow.detachEvent( "onclick", TextViewControl_displayHows );
		  }
		}

    // Why direction
    var whyArrow = document.getElementById("TextViewCompassWhy");
    if( typeof( whyArrow ) == "object" )
    {
	    if( compass.directions & 2)
	    {
		    whyArrow.childNodes[0].src = CompassWhyOn.src;
		    whyArrow.attachEvent( "onclick", TextViewControl_displayWhys );
		  }
	    else
	    {
		    whyArrow.childNodes[0].src = CompassWhyOff.src;
		    whyArrow.detachEvent( "onclick", TextViewControl_displayWhys );
		  }
		}

    // What direction
    var whatArrow = document.getElementById("TextViewCompassWhat");
    if( typeof( whatArrow ) == "object" )
    {
	    if( compass.directions & 4)
	      whatArrow.childNodes[0].src = CompassWhatOn.src;
	    else
		    whatArrow.childNodes[0].src = CompassWhatOff.src;
		}

    // What Is Direction
    var whatisArrow = document.getElementById("TextViewCompassWhatIs");
    if( typeof( whatisArrow ) == "object" )
    {
	    if( compass.directions & 8)
		    whatisArrow.childNodes[0].src = CompassWhatIsOn.src;
	    else
		    whatisArrow.childNodes[0].src = CompassWhatIsOff.src;
		}
		
		// set the properties to get the compass displaying in the right place
    compass.style.position = "absolute";
    
    var miniCompass = document.getElementById( 'TextViewControl_miniCompass' );
    if( typeof(miniCompass) == "object" && miniCompass != null )
    {
      compass.style.left = parseInt(miniCompass.style.left) - 24;
      compass.style.top = parseInt(miniCompass.style.top) - 24;

      // if the compass has fallen off the edge of the screen then bump it back on
      if( parseInt(compass.style.left) < 0 )
        compass.style.left = '0px';    
      if( parseInt(compass.style.top) < 0 )
        compass.style.top = '0px';    
    
      compass.style.visibility = "visible";
    }
  }
  
  // at this point we want to clean the focused knowde...
  TextViewControl_CleanFocusedKnowde();
}

// this is attached to an event on the compass, we can't attach methods that use parameters
function TextViewControl_displayHows()
{
  TextViewControl_HideCompass();
  TextViewControl_displayCascade(document.getElementById('textviewCompass').cascadeItem, 1);
}

// this is attached to an event on the compass, we can't attach methods that use parameters
function TextViewControl_displayWhys()
{
  TextViewControl_HideCompass();
  TextViewControl_displayCascade(document.getElementById('textviewCompass').cascadeItem, 2);
}

// cleans the focused knowde so that everything is ready to start again
function TextViewControl_CleanFocusedKnowde()
{
  // grab the centred knowde
  var focusedKnowde = document.getElementById("TextViewControl_CentredKnowde");
  if( typeof(focusedKnowde) == "object" && focusedKnowde != null )
  {
    // as it's a valid object hide all the child cascades and reset the child id of the item..
    TextViewControl_hideCascade( focusedKnowde.visibleChild );
    focusedKnowde.childNodes[0].childId = "unknown";
  }
}

function TextViewControl_DisplayCentredKnowde( _HKLink, e )
{
	//IG - get the innertext here, rather than passing it in, so we don't have to worry about JS reserved chars
  //var _strText = GetInnerText(_HKLink);
  var strText;
  if( typeof(_HKLink.KnowdeText) == "string" && _HKLink.KnowdeText != null )
    strText = _HKLink.KnowdeText; 
  else
    strText = "Unable to find Knowde text";
    
  // make sure all our inputs are what we expect them to be
  if( typeof( _HKLink ) == "object" && _HKLink != null && typeof( strText ) == "string" && strText != null )
  {
    // grab the centred Knowde box and make sure it's valid for use
    var centredKnowde = document.getElementById( "TextViewControl_CentredKnowde" );
    if( typeof( centredKnowde ) == "object" && centredKnowde != null )
    {
      // close everything down as we are starting again
      TextViewControl_HideCompass();
      TextViewControl_hideCascade( centredKnowde );
      TextViewControl_HideMiniCompass();    
    
      // set the innertext, directions and knowde id. these are the things we need in the link on the page
      SetInnerText(centredKnowde.childNodes[0],strText);
      centredKnowde.childNodes[0].knowdeId = _HKLink.knowdeId;
      centredKnowde.childNodes[0].directions = _HKLink.directions;
      
      centredKnowde.style.position = "absolute"
      if (_HKLink.className=="TextViewSelectedHKTag")
      {
		centredKnowde.style.left = _HKLink.offsetLeft+5;
		centredKnowde.style.top = _HKLink.offsetTop+15;
	  }
	  else
	  {
		centredKnowde.style.left = e.offsetX;
		centredKnowde.style.top = e.offsetY;
	  
	  } 
      // make it visible
      centredKnowde.style.visibility = "visible";
    } 
  }
}

function TextViewControl_HideEverything()
{
  // close everything down as we are starting again
  TextViewControl_HideCompass();
  var centredKnowde = document.getElementById( "TextViewControl_CentredKnowde" );
  if( typeof( centredKnowde ) == "object" && centredKnowde != null )
    TextViewControl_hideCascade( centredKnowde );
  TextViewControl_HideMiniCompass();   
}

// gets the compass from the page and hide it if it is valid
function TextViewControl_HideCompass()
{
  var compass = document.getElementById( 'textviewCompass' );
  if( typeof(compass) == "object" && compass != null )
    compass.style.visibility = "hidden";
}

// gets the mini compass from the page and hide it if it is valid
function TextViewControl_HideMiniCompass()
{
  var compass = document.getElementById( 'TextViewControl_miniCompass' );
  if( typeof(compass) == "object" && compass != null )
    compass.style.visibility = "hidden";
}

function TextViewControl_displayCascade( _CascadeItem, _mode )
{
  // if the cascade item is not an object OR the mode is not a number THEN get out of here
  if( typeof(_CascadeItem) != "object" || typeof(_mode) != "number" || _CascadeItem == null || _mode == null )
    return;
  
  var childCascade;
  
  // if the child id is 'unknown' then we first need to load it onto the page 
  if( _CascadeItem.childId == "unknown" )
  {
    
    var KnowdeServerUrl = TextViewAshxFile + "?KnowdeId=" + _CascadeItem.knowdeId + "&Mode=" + _mode;
    
    // TextViewControl_appendCascade( _CascadeItem, _mode );    
    var xmlIsland = document.getElementById("TextViewControl_xmlIsland");
    var newHtml = GetHtmlFromAshx(KnowdeServerUrl, xmlIsland);
    /*
    // do the actual load
    var dataIsland = xmlIsland.XMLDocument;
    dataIsland.async = false;
    dataIsland.load( KnowdeServerUrl );
    
    var error = dataIsland.parseError;
    */
    
    //if( error.errorCode == 0 )
    if(newHtml != 'error')
    {
      // TODO: should all our stuff be in a document fragement...??
      // document.createDocumentFragment(); 
      // is this wrong, we need to place this inside an existing element?  
      var newCascade = document.createElement( "div" );
      //newCascade.innerHTML = xmlIsland.XMLDocument.documentElement.xml;
      newCascade.innerHTML = newHtml;
      TextViewControl = document.getElementById("TextViewControl1");
      TextViewControl.insertBefore( newCascade, document.getElementById("TextViewControl_miniCompass") );
      childCascade = newCascade.firstChild; 
      
      // place the child id into the correct place
      _CascadeItem.childId = childCascade.id;
    }
    else // there isn't any children, set this to none so we don't waste time and effort trying to download it again
      _CascadeItem.childId = "none";
  }
  else if( _CascadeItem.childId != "none" ) // if it's none then there isn't one to load or display
  {
    // grab the child id and grab the element
    childCascade = document.getElementById( _CascadeItem.childId );
  }
  
  // do we need to hide any existing cascades?
  if( _CascadeItem.parentNode.hasVisibleChild == true )
    TextViewControl_hideCascade( _CascadeItem.parentNode.visibleChild );
  
  if( childCascade != null )
  {
    // make sure that the parent element knows it has a child visible
    if( _CascadeItem.parentNode.type == "compass" )
    {
      TextViewControl_hideCascade( _CascadeItem.parentNode.parentNode.visibleChild );
      _CascadeItem.parentNode.parentNode.hasVisibleChild = true;
      _CascadeItem.parentNode.parentNode.visibleChild = childCascade;  
    }
    else
    {
      _CascadeItem.parentNode.hasVisibleChild = true;
      _CascadeItem.parentNode.visibleChild = childCascade;  
    }
    
    // we now need to position them, this depends upon the mode we are using
    switch( _mode )
    {
      case 2: // why
        // TODO: we need to move everything for whys id they go off the edge of the screen
        childCascade.style.top = _CascadeItem.offsetTop + _CascadeItem.parentNode.offsetTop;

        if(GetPixelWidth(childCascade) == 0 )
          childCascade.style.width = childCascade.currentStyle.width;
        childCascade.style.left = parseInt(_CascadeItem.parentNode.style.left) - GetPixelWidth(childCascade);
       
        // shunt the cascade to the right a bit...
        childCascade.style.left = parseInt(childCascade.style.left) + 1;
        
        // if the cascade has fallen off the edge of the screen then move everything across to fit
        if( parseInt(childCascade.style.left) < 0 )
        {
          var iOffset = parseInt(childCascade.style.left) - 10;
          TextViewControl_repositionCascades( document.getElementById( 'TextViewControl_CentredKnowde' ), iOffset );
          TextViewControl_repositionCascades( document.getElementById( 'TextViewControl_miniCompass' ), iOffset );
        }
          
        break;
      case 1: // how
        childCascade.style.top = _CascadeItem.offsetTop + _CascadeItem.parentNode.offsetTop;
        if( GetPixelWidth(_CascadeItem.parentNode) == 0 )
          _CascadeItem.parentNode.style.width = _CascadeItem.parentNode.currentStyle.width
      
        childCascade.style.left = parseInt(_CascadeItem.parentNode.style.left) + GetPixelWidth(_CascadeItem.parentNode);
        childCascade.style.left = parseInt(childCascade.style.left) - 1;
        
        
        TextViewControl.scrollLeft += ( TextViewControl.scrollWidth - TextViewControl.scrollLeft - TextViewControl.clientWidth );
        
        break;
    }
        
    // finally show the cascade and make sure we can actually see it
    childCascade.style.visibility = "visible";
    
    //childCascade.scrollIntoView();
    
  }
}

// shifts everything over to the right as you can't scroll to a minus number
function TextViewControl_repositionCascades( _Cascade, _offset )
{
  // only do this if the cascade is a real object and the offset is a number
  if( typeof(_Cascade) == "object" && typeof(_offset) == "number" && _Cascade != null && _offset != null )
  {
    if( _Cascade.hasVisibleChild )
      TextViewControl_repositionCascades( _Cascade.visibleChild, _offset );
  
    _Cascade.style.left = parseInt(_Cascade.style.left) - _offset;
  }
}

// hides the cascade and all it's children in a nice recursive way
function TextViewControl_hideCascade( _Cascade )
{
  // only attempt this if _Cascade is an object
  if( typeof(_Cascade) == "object" && _Cascade != null )
  {
    // if there are visible children then hide them aswell
    if( _Cascade.hasVisibleChild )
      TextViewControl_hideCascade( _Cascade.visibleChild );
    
    _Cascade.style.visibility = "hidden";
    _Cascade.hasVisibleChild = false;  
    _Cascade.visibleChild = null;
  }
}

// displays the mini compass
function TextViewControl_DisplayMiniCompass( _Cascade )
{
  // only attempt this if the cascade is a real object
  if( typeof( _Cascade ) == "object" && _Cascade != null )
  {
    var minicompass = document.getElementById("TextViewControl_miniCompass");
    if( typeof( minicompass ) == "object" && minicompass != null )
    {
      // set the cascade item, so that this can be passed through
      minicompass.CascadeItem = _Cascade;
        
      var centredKnowde = document.getElementById( "TextViewControl_CentredKnowde" );
      if( typeof( centredKnowde ) == "object" && centredKnowde != null )
      {
        minicompass.style.left = centredKnowde.style.left;      
        minicompass.style.left = parseInt(minicompass.style.left) - 18;
        minicompass.style.top = centredKnowde.style.top;  
        minicompass.style.top = parseInt(minicompass.style.top) + 2;    
        minicompass.style.visibility = "visible";    
      }
     
    }  
  }
}

function TextViewControl_onFocus()
{//debugger;
  clearTimeout(textViewFocusTimer);
  
  // if the preview help control is open, don't allow text view editing
  /*var helpBox = document.getElementById("KGHelpControlID1");
  if(helpBox != null && helpBox.className == "OverlayPosition")
  {
    // move the focus to somewhere else 
    var focusOnObj = document.getElementById('SiteHeader_KGSearchControl1_KGSearchTextBox'); //
    focusOnObj.focus();
    focusOnObj.select();

    DisplayClosePreviewWarningBox();
    
    // focus on the button
    focusOn("closePreviewMessageButton");    
    
    return false;
  }*/
  
  // need this if share the same editing toolbar with mapview
  if (window.KGTextViewEditingToolbar_ChangeEditbarMode && m_bTextViewWritable == true)
    KGTextViewEditingToolbar_ChangeEditbarMode("TextView");
  
  if(m_bShowClickEditHint == 1)
  {
    m_EditFrame = document.getElementById("TextViewEditFrame-k"+m_strSelectedKnowdeID);
    if(m_EditFrame != null && m_EditFrame.contentWindow.document.body != null)
    {
      if(m_EditFrame.contentWindow.document.body.innerHTML.toLowerCase().indexOf('images/clickedit') != -1)
      {
        /*if((m_EditFrame.contentWindow.document.selection && m_EditFrame.contentWindow.document.selection.type == 'Control'))
        {
              //m_EditFrame.contentWindow.document.body.innerHTML = GetDefaultTextViewContent(m_strSelectedKnowdeID, 0);//'<p></p>'; 
              //var range = m_EditFrame.contentWindow.document.selection.createRange();
              //range.collapse(true);
              m_EditFrame.contentWindow.document.execCommand("Cut", false, null);
        }*/
        //else
        //{
            m_EditFrame.contentWindow.document.body.innerHTML = GetDefaultTextViewContent(m_strSelectedKnowdeID, 0);//'<p></p>'; 
        //}
        m_EditFrame.contentWindow.document.body.focus();
      }
    }
    m_bShowClickEditHint = 0;
  }
}

function TextViewControl_onMouseUp()
{
  if(window.KGTextViewEditingToolbar_UpdateStyleSelector)
    KGTextViewEditingToolbar_UpdateStyleSelector();
  if(window.KGTextViewEditingToolbar_UpdateTextFormatBtns)
    KGTextViewEditingToolbar_UpdateTextFormatBtns();
  if(window.KGTextViewEditingToolbar_UpdateCutCopyPasteBtns)
    KGTextViewEditingToolbar_UpdateCutCopyPasteBtns();
  copySelection();
  TextViewUnhighlightTickerText();
  
  
  // Set 'Set ticker text' to active
  if(m_textViewMode == 'KNOWDEDOC' && Active_KGID == globalHelpID)
  {
		var button = document.getElementById("KGButtonToolbar_SetTicker");
		button.className = "ButtonToolbar_TextButtonDivActive";  
  }
  
}

var TextviewKeypressTimeout;

function TextViewControl_KeyPress()
{

	// Sets a timeout on the call to TextViewControl_handleTextChanged.
	// If the user presses another key before this happens, the timeout is cancelled,
	// so the call is only made once the user pauses while typing.
	clearTimeout(TextviewKeypressTimeout);
	TextviewKeypressTimeout = setTimeout('TextViewControl_handleTextChanged()', 500);
  
	TriggerAutoSave();  
}

function TextViewControl_KeyDown(e)
{
  //debugger;
  e = e || m_EditFrame.contentWindow.window.event;
  if (e != null && e.keyCode == 13 && !e.shiftKey) // capture the enter key
  {
    var tempTR = null;
    if(m_EditFrame.contentWindow.getSelection)
      tempTR = GetRangeObject(m_EditFrame.contentWindow.getSelection());
    else if(m_EditFrame.contentWindow.document.selection)
      tempTR = m_EditFrame.contentWindow.document.selection.createRange();
      
    if(tempTR != null && tempTR.pasteHTML) //check if an image isn't selected
    {
      //tempTR.pasteHTML("<br></br>");
      var temporary = unescape("%0A");
      m_EditFrame.contentWindow.document.execCommand('paste',"",temporary);
    }
    else if(tempTR != null)
    {
      tempTR.collapse(false);
      var temporary = unescape("%0A");
      var ele = m_EditFrame.contentWindow.document.createElement('div');
      ele.innerHTML = temporary;
      tempTR.insertNode(ele.firstChild);
    }
    return false;
  }
  else
  {
    return true;
  }
}


function TriggerAutoSave()
{
  m_textViewChanged = 1;
  
  if(m_autoSaveTimeOut != null)
    clearTimeout(m_autoSaveTimeOut);
  else
  {
    // initialize utc time
    var localTime = new Date();
    m_lastAutoSaveTime = localTime.getTime() + (localTime.getTimezoneOffset() * 60000 );
  }
  // Sets a timeout for check whether need to auto saving the textview if no key or mouse action for a while
  // AutoSave will only save the text view in the given interval, e.g. 10 seconds
  m_autoSaveTimeOut =  setTimeout('AutoSaveTextView()', m_autoSaveInactivePeriod * 1000);
  
  SetAutoSaveButtonStatus(-1);
}

function TextViewControl_handleTextChanged()
{
  // update the Style selection drop list
  if(window.KGTextViewEditingToolbar_UpdateStyleSelector)
    KGTextViewEditingToolbar_UpdateStyleSelector();
  // update text format button selections
  if(window.KGTextViewEditingToolbar_UpdateTextFormatBtns)
    KGTextViewEditingToolbar_UpdateTextFormatBtns();
  // check whether to activate the undo/redo buttons or not
  if(window.KGTextViewEditingToolbar_UpdateUndoRedoBtns)
    KGTextViewEditingToolbar_UpdateUndoRedoBtns();
  // check whether to activate the cut/copy/paste buttons or not
  if(window.KGTextViewEditingToolbar_UpdateCutCopyPasteBtns)
    KGTextViewEditingToolbar_UpdateCutCopyPasteBtns();
}

function EditFrameContentWindowExists()
{
  var exists = true;
  if (m_EditFrame == null)
    exists = false;
  else if(typeof(m_EditFrame.contentWindow) != "object")
    exists = false;
  else if(m_EditFrame.contentWindow == null)
    exists = false;

  return exists;
}

function SaveCurrentlyEditingTextView(_repopulate)
{
   // Fix for bug whereby a WHAT's text view is not saved when editing a WHAT
  if(m_bTextViewWritable == true && EditFrameContentWindowExists())
  {
     m_EditFrame.contentWindow.document.contentEditable = "false";
    
    // save text view
    var saveArgs = 'Action=AutoSave|KGId=' + Active_KGID + '|KnowdeId=' + m_strSelectedKnowdeID; //can't use this, won't work in add knowde, returnKnowdeID(globalLastSelectedKnowde)
    if(_repopulate == false)
      saveArgs += '|Repopulate=false';
    SaveTextView(saveArgs);
    // only turn off editing mode when click non-sibling knowde
    if(m_bLoadSiblingKnowde == false)
      m_bTextViewWritable = false;
  }
  else if(m_bTextViewWritable == false)
  {
    // clear text view auto save timeout
    if(m_autoSaveTimeOut != null)
        clearTimeout(m_autoSaveTimeOut);
  }
}

function TextViewControl_onMouseOut()
{
  if(m_bTextViewWritable == true && m_textViewChanged == 1)
  {
    // user move mouse out of the editing area, trigger auto save
    // in case user navigate out by click a category or go to other link
    
    if(m_autoSaveTimeOut != null)
        clearTimeout(m_autoSaveTimeOut);
        
      var div = m_EditFrame.contentWindow.document.getElementById('k' + m_strSelectedKnowdeID);
      var adiv = m_EditFrame.contentWindow.document.getElementById('k' + m_strSelectedKnowdeID + '-active');
      var content = '';
      
      if(adiv != null)
        content = adiv.innerHTML;
      else if(div != null)
        content = div.innerHTML;
      else
        content = m_EditFrame.contentWindow.document.body.innerHTML;
        
      if(content.length > 0)
      {
        m_bLoadSiblingKnowde = true;
        SaveTextView('Action=AutoSave|Repopulate=false|KGId=' + m_strSelectedKGID + '|KnowdeId=' + m_strSelectedKnowdeID);
      }
  }
}

function SetAutoSaveButtonStatus(_status)
{
    var btn = document.getElementById('TextViewAutoSaveBtn');
    if(_status == 1)
    {
      //KGTextTabControl_HideOrShowLoadingDiv(true, 'Saving...');
      SetInnerText(btn,'Saving...');
      btn.className = 'ButtonToolbar_TextViewAutoSaveBtnRed';
    }
    else if(_status == 0)
    {
      //KGTextTabControl_HideOrShowLoadingDiv(false);
       m_EditFrameDiv = document.getElementById('TextViewEditFrameDiv');
       // only show Saved if the Saving was showing
      if(btn.className == 'ButtonToolbar_TextViewAutoSaveBtnRed')
      {
        SetInnerText(btn,'Saved');
        btn.className = 'ButtonToolbar_TextViewAutoSaveBtnOff';
      }
    }else
    {
      SetInnerText(btn,'');
      btn.className = 'ButtonToolbar_TextViewAutoSaveBtnOn';
    }
}

function ShowOrHideSavingDiv(_status, _message, _top, _left)
{
  if (m_textViewMode == "KNOWDEDOC")
  {
    if(_status == 1)
    {
      //KGTextTabControl_HideOrShowLoadingDiv(true, 'Saving...');
      SetAutoSaveButtonStatus(_status);
    }
    else
    {
      //KGTextTabControl_HideOrShowLoadingDiv(false);
      window.setTimeout('SetAutoSaveButtonStatus(0)', 1000);
    }
  }
  else if (m_textViewMode == "HKGROUPDOC")
  {
    if(_status == 1)
    {
      //ConfigureCommunitySpace_ShowOrHideHKDocBusyDiv(true, "Saving...");
      SetAutoSaveButtonStatus(_status);
    }
    else
    {
      //ConfigureCommunitySpace_ShowOrHideHKDocBusyDiv(false);
      window.setTimeout('SetAutoSaveButtonStatus(0)', 1000);
    }
  }
}

/*function TextView_RTEonkeyup()
{
  //SetupKnowdeTextViewDiv(m_strSelectedKnowdeID);
  m_EditFrame.style.height = m_EditFrame.contentWindow.document.body.scrollHeight + m_editFrameHeightMargin + 'px';
}
*/

function DisplayClosePreviewWarningBox()
{
  var browserName = navigator.userAgent;
  
  if(browserName.indexOf('Firefox') != -1)
  {
    // OK button keep losing focus so have to click twice in FF
    var messageBox = document.getElementById("ClosePreviewWindowMessageDiv");
    
    if(messageBox == null)
    {
      messageBox = document.createElement("div");
      messageBox.setAttribute("id", "ClosePreviewWindowMessageDiv");
      messageBox.style.width = "450px"
      messageBox.style.height = "80px";
      messageBox.style.position = "absolute";
      messageBox.style.zIndex = TopZIndex();
      
      // position
      messageBox.style.top = screen.availHeight/2 - 150;
		  messageBox.style.left = screen.availWidth/2 - 225;
      messageBox.innerHTML = "<div class='MessageBox' style='font-size: x-small; padding: 10px;' ><nobr>Please close the preview full document window to continue editing.</div>";
      
      var parentControlDiv = document.getElementById('Form1');
      InsertAdjacentElement(parentControlDiv,"beforeEnd", messageBox);
    }
    else
    {
      messageBox.style.zIndex = TopZIndex(); //Show on top of other items
      
      if (messageBox.style.display == 'none')
        messageBox.style.display = 'block';  
      else
      {
        var anim = new YAHOO.util.Anim('ClosePreviewWindowMessageDiv', AniFadeInMapItemAttributes, 0, YAHOO.util.Easing.easeNone);
        anim.animate(); // Make the notice visible immediately (the 0 parameter)
      }
    }
    
    setTimeout("FadeMapItemOut('ClosePreviewWindowMessageDiv')", 4000);
    
  }else
  {
    var messageBox = document.getElementById("ClosePreviewWindowMessageDiv");
    
    if(messageBox == null)
    {
      messageBox = document.createElement("div");
      messageBox.setAttribute("id", "ClosePreviewWindowMessageDiv");
      messageBox.style.width = "450px"
      messageBox.style.height = "80px";
      messageBox.style.position = "absolute";
      messageBox.style.zIndex = TopZIndex();
      
      // position
      messageBox.style.top = screen.availHeight/2 - 150;
		  messageBox.style.left = screen.availWidth/2 - 225;
      // onmouseover='focusOn(\"closePreviewMessageButton\");'
      messageBox.innerHTML = "<div class='MessageBox' style='padding: 10px;' ><table border='0' cellpadding='5' cellspacing='0'><tr><td style='font-size:x-small;'><nobr>Please close the preview full document window to continue editing.</td></tr><tr><td align='center'></nobr><button id ='closePreviewMessageButton' type='button' onclick='ClosePreviewWarningBox()' style='width: 50px;'>Ok</button></td></tr></table></div>";
      
      var parentControlDiv = document.getElementById('Form1');
      InsertAdjacentElement(parentControlDiv,"beforeEnd", messageBox);
    }
    else
    {
      messageBox.style.zIndex = TopZIndex(); //Show on top of other items
    }
  }
}

function ClosePreviewWarningBox()
{
  var messageBox = document.getElementById("ClosePreviewWindowMessageDiv");
  if(messageBox != null)
  {
   var parent = messageBox.parentNode;
   parent.removeChild(messageBox);
  }
}

function HandleTextTabResize()
{
    //m_textViewSpanResizeTimeOut = setTimeout('HandleTextViewSpanResize()', 1000); 
    /*frame = document.getElementById("TextViewEditFrameDiv");
    if(m_EditFrameDiv != null && m_KnowdeIdList !=  null && m_KnowdeIdList.length > 0)
    SetupKnowdeTextViewDivs();*/
   
    m_textFrameScrollTimeOut = setTimeout('HandleTextFrameScroll()', 1000);

}

function HandleTextViewSpanResize()
{
  if(m_textViewSpanResizeTimeOut != null)
  {
      clearTimeout(m_textViewSpanResizeTimeOut);
      m_textViewSpanResizeTimeOut =  null;
  }

  if(globalShowingWebDoc == true || m_bTextViewWritable == false || m_textViewControlSpanFixedSize != 1) //not text view
    return;
    
  //debugger;
  
  
   if(m_textViewControlSpanFixedSize == 1 && m_bTextViewWritable == true)
    {
      //debugger;
      var container = document.getElementById('TCC_moretext'); //TextViewControlContent
      var tvcontrol = document.getElementById('TextViewControl1');
      if(container != null && tvcontrol != null)
      {
        tvcontrol.style.height = (container.style.height.replace('px','') - 75) + 'px';
        if(container.style.width.indexOf('%') != -1)
          tvcontrol.style.width = '550px';
        else
          tvcontrol.style.width = (container.style.width.replace('px','')- 5) + 'px';

      }
      
    }
}

/****************************************************
 TextTabControl
 ***************************************************/
 
 var m_textFrameLoadingDivTimeOut;
 var m_textFrameCallbackStatus = 'none';
 var m_textTabFrame;
 
 var m_textFrameScrollTimeOut = null;
 var m_bTextFrameManualScroll = false;
 var m_textFrameScrollMoreOnTopTimeOut;
 var m_textFrameScrollDelay = 50; //ms
 var m_bTextFrameLoadSiblingKnowde = false;
 
 // most of these variables are now used in TextViewControl.js
var m_tickerKnowdeID = '';

// for aggregate text view partial loading
var m_FrameLoadedKnowdeIdList = new Array();
var m_FrameLoadedKnowdeIdString = '';
var m_FrameUnLoadedKnowdeIdString = '';
var m_FrameKnowdePathString = '';

// knowde and client knowde list
var m_FrameKnowdeIdsArray = new Array();
var m_FrameKnowdeClientIdsArray = new Array();

var m_FrameDivIDArray = new Array();
var m_FrameDivPathArray = new Array();
var m_FrameDivHeightArray = new Array();

var m_strFrameSelectedKGID = '';
var m_strFrameSelectedKnowdeID = '';
var m_strFrameSelectedKnowdeDBID = '';
var m_strFrameSelectedKnowdeContext = '';
var m_strFrameCentreKnowdeContext = '';
var m_strFrameViewMode = '';

var m_frameDivGapHeight = 15;
var m_frameScrollTopOffSet = 50;

var m_currentTextViewViewMode = "Single"; // Single or Full
var m_textViewViewModeChanged = false;

var Active_KnowdeID_Text = '';

var m_textViewControlSpanFixedSize = 0; // for firefox
var m_textViewSpanResizeTimeOut;

var m_textFrameHighlightColor = '#EAF4F7'; 
var m_textFrameHighlightBorderLeftStyle = '2px #A7A9E2 solid'; //8EA4DB A7A9E2
var m_textFrameHighlightBorderLeftPadding = '5';

function AutoLoadTextViewForKnowde(_action, _knowdeID)
{
  //if (m_IsEditFromNewKnowde == true) // check in handleKnowdeClick instead
    //return;
  // auto load the currently selected knowde textview
  var currentKnowdeID = objectiveID;
  if(_knowdeID != null)
    currentKnowdeID = _knowdeID;
  else 
  {
    var whatId = '';
    if(_action == 'ChangeTab')
    {
	    whatId = GetGlobalHighlightedWhatId();
    }
    if(whatId != '')
      currentKnowdeID = whatId;
    else if(globalLastSelectedKnowde != null)
      currentKnowdeID = returnKnowdeID(globalLastSelectedKnowde);
  }  
  
  if(_action != null && _action != 'StopEditing' && _action != 'StartSingleTextEditing')
  {
    KGTextTabControl_HideOrShowTextViewEditButton(false, true);
  }
  
  if (currentKnowdeID != null && currentKnowdeID != "")
  {
      if(_action != null && (_action == 'StopEditing' || _action == 'StartSingleTextEditing'))
      {
        if(_action == 'StopEditing')
          SwitchTextTabControlMode(false);
        SwitchTextViewViewMode("Single");
      }
          
      SetSessionProperty('TickerKnowde', currentKnowdeID);
      m_tickerKnowdeID = currentKnowdeID;
      if ((m_bEditable == false && _action != 'StartSingleTextEditing') 
          || (_action != 'StartEditing' && m_currentTextViewViewMode == 'Full'))
      {
          // load text view
            DisplayTextViewInTab("TextForSpecifiedKnowde", globalSplitterSetting, "true"); 
            //KGTextTabControl_HideOrShowPreviewFullTVButton(false);
            globalLastTickerAction = "TextForSpecifiedKnowde" + currentKnowdeID;
      }else // edit mode
      {
         if(_knowdeID == null && m_IsEditFromNewKnowde == true) // change tab reload when in edit new knowde mode
         {
            // don't load the text yet, make sure the option div is hidden 
            // need this for create new kg in callback or auto enter edit mode for kg that do not have any knowde yet
            SwitchTextTabControlMode(true);
            SwitchTextViewViewMode("Single");
         }
         else if(IsLoadTextViewForKnowde(currentKnowdeID))
         {
            // moved text view save to a function for easy reading of handleKnowdeClick
	          TextViewSaveFromKnowdeClick(_knowdeID);
	          
	          if(_action == null || _action.indexOf('-Edit') == -1) // not what/whatIs edit
	          {
	            var actionPrefix = 'KnowdeSelected';
	            if(_action != null && (_action.indexOf('WhatSelected') == 0 || _action.indexOf('WhatIsSelected') == 0) )
	              actionPrefix = 'KnowdeHover';
  	          
              DisplayTextViewInTab(actionPrefix + "-ReloadTextView", globalSplitterSetting, "true"); 
              //KGTextTabControl_HideOrShowPreviewFullTVButton(false);
              globalLastTickerAction = actionPrefix + "-ReloadTextView" + currentKnowdeID;
            }else
            {
               // clear textview
              /*m_EditFrameDiv = document.getElementById('TextViewEditFrameDiv');

              if(m_EditFrameDiv != null)
                m_EditFrameDiv.innerHTML = "";
              globalLastTickerAction = "";  
              m_textFrameCallbackStatus = 'none';*/
            }
         }
      }
      globalAutoLoadTextView = false;
  }
}

function IsLoadTextViewForKnowde(_currentKnowdeID)
{
  //check whether knowdeID changed since last load
  return !(globalLastTickerAction && globalLastTickerAction.length > 0 && globalLastTickerAction == ("KnowdeSelected-ReloadTextView" + _currentKnowdeID))
}

function TextViewSaveFromKnowdeClick(_knowdeID)
{
  // XD - seems the saving will only occur after the SetSessionProperty('PageSession_KGMapContext', sessionString) later on
  //      so the text view will be saved to the wrong map, therefore pass in extra args
  if(m_bTextViewWritable == true && m_knowdeDeleted == 0 && EditFrameContentWindowExists())
  {
    m_EditFrame.contentWindow.document.contentEditable = "false";
    // save text view
    var saveArgs = 'Action=AutoSave|KGId=' + Active_KGID + '|KnowdeId=' + m_strSelectedKnowdeID; //can't use this, won't work in add knowde, returnKnowdeID(globalLastSelectedKnowde)
    var tvChanged = ChangeSelectedTextView(_knowdeID);
    m_bLoadSiblingKnowde = false;
    if(tvChanged == false)
    {
      saveArgs += '|Repopulate=false';
      // the line below need to be taken out if we change back to mutliple knowde text view again
      m_bLoadSiblingKnowde = true;
    }
    SaveTextView(saveArgs);
    // only turn off editing mode when click non-sibling knowde
    if(m_bLoadSiblingKnowde == false)
      m_bTextViewWritable = false;
    //setTimeout("handleKnowdeClick('" + _parentKnowdeDiv + "','" + _mapDirection + "','" + _doCallback + "','" + _allowEdit + "')", 500); 
  }
  else
  {
    // clear text view auto save timeout
    if(m_autoSaveTimeOut != null)
      clearTimeout(m_autoSaveTimeOut);
        
    m_bLoadSiblingKnowde = false;
  }
}
 
function DisplayTextViewInTab(_message, _params, _openText, _kgId)
{
 
  if (!(_message == "TextView" ||  _message=="TextForSpecifiedKnowde" || _message.indexOf('ReloadTextView') != -1))
    return;//We're no longer using the xml help

  // make sure the more text tab is selected
  //if(globalVisibleTab.indexOf('moretext') == -1)
    //ChangeTab('moretext', 'More Text');
  
  //debugger;
  globalHelpTopicKey = _message;
  
  if(_message.indexOf('ReloadTextView') != -1)
  {
    SwitchTextTabControlMode(true);
    SwitchTextViewViewMode("Single");
  }
  else
    SwitchTextTabControlMode(false);

  if(globalHelpTopicKey == "TextView" || globalHelpTopicKey == "TextForSpecifiedKnowde" || globalHelpTopicKey.indexOf("ReloadTextView") != -1)
  {
    m_bTextFrameLoadSiblingKnowde = false;
     var kgid = Active_KGID;
    if(_kgId != null && _kgId > 0)
      kgid = _kgId;
    var params = '';
    if(_message=="TextForSpecifiedKnowde" || _message == "TextView")
    {
      if(m_textViewViewModeChanged == false && m_currentTextViewViewMode == "Full" && m_strFrameSelectedKGID != '' && m_strFrameSelectedKGID == kgid )
        //&& ((m_strFrameSelectedKnowdeID != '' && m_strFrameSelectedKnowdeID == m_tickerKnowdeID) || (m_strFrameSelectedKnowdeDBID != '' && m_strFrameSelectedKnowdeDBID == m_tickerKnowdeID)))
      {
        m_bTextFrameLoadSiblingKnowde = true;
      }
      
      if(m_tickerKnowdeID != '')
      {
        var kndPathContext = FindSelectedTextFrameKnowdePathContext(m_tickerKnowdeID);
        var knowdeChanged = ChangeSelectedTextFrameKnowde(m_tickerKnowdeID, kndPathContext);  
      }
      ///debugger;
      params = GetTextViewCallBackArgs(_kgId);
    }
    
     // No point in reloading the text if its already being displayed!
     if(_message.indexOf('ReloadTextView') != -1  || _message.indexOf('TextForSpecifiedKnowde') != -1  || (m_tickerKnowdeID != Active_KnowdeID_Text || m_currentTextViewViewMode == 'Full'))
     {
        KGTextTabControl_CallbackTrigger(_message, params); //, globalHelpTopicParams); //We're no longer using the xml help
     }
     
   }    
   
  // reset the value 
  m_textViewViewModeChanged = false;
  
}

function KGTextTabControl_CallbackTrigger_Wrapped(_key, _params, _callbackScript)
{
  // Make sure we clear the contents of the document window
  if(_key != 'NewWindowTextView' && m_bTextFrameLoadSiblingKnowde == false)
    ClearTextTabFrame(false);

  // show textview view mode option if in read mode
  // need to use set time out otherwise iframe height become 0 in Safari and Chrome
  if(m_bEditable == true || m_bWhatTextWritable == true)
  {
    window.setTimeout('KGTextTabControl_HideOrShowTextViewOptionDiv(false)',5);
    window.setTimeout('KGTextTabControl_HideOrShowPreviewFullTVButton(true)',5);
  }
  else
  {
    window.setTimeout('KGTextTabControl_HideOrShowTextViewOptionDiv(true)', 5);
    window.setTimeout('KGTextTabControl_HideOrShowPreviewFullTVButton(false)',5);
  }
  
  // hide or show the textview edit button for what text editing
  if(m_tickerKnowdeID != null && m_tickerKnowdeID != '' && GetGlobalHighlightedWhatId() == m_tickerKnowdeID
  && globalLastHighlightedWhat != null && m_IsEditFromNewWhat != true && globalLastHighlightedWhat.getAttribute('IsUserKI') == 'true'
  && AllowWhatEditOnly == 1)
    window.setTimeout('KGTextTabControl_HideOrShowTextViewEditButton(true)', 5);
  else
    window.setTimeout('KGTextTabControl_HideOrShowTextViewEditButton(false)', 5);

      
  var args;
  //debugger;
  // Construct the callback arguments
  if(_key != null)
  { 
    args = 'key=' + _key + "|params=" + _params;
    
    if(args.length > 0)
    {
      m_textFrameCallbackStatus = 'trigger';
      if(_key.indexOf('ReloadTextView') == -1)
      {
        // show loading div
        if(args.indexOf('LoadTrigger=Scrolling') == -1)//(m_bTextFrameLoadSiblingKnowde == false)
        {
          if(m_textFrameLoadingDivTimeOut != null)
          {
            clearTimeout(m_textFrameLoadingDivTimeOut);
            m_textFrameLoadingDivTimeOut = null;
          }
          KGTextTabControl_HideOrShowLoadingDiv(true, 'Loading...');
          //m_textFrameLoadingDivTimeOut = window.setTimeout("KGTextTabControl_HideOrShowLoadingDiv(true, 'Loading...')",1);
        }
      }
      // trigger the callback
      eval(_callbackScript);  
    }
  }
}

function KGTextTabControl_CallbackDone(_args, _context)
{
  // Check for a session time out before completing the callback
  if (CheckSessionTimeout())
    return;
  m_textFrameCallbackStatus = 'done';
  m_textTabFrame = document.getElementById("TextTabFrame");

  var action = '';
  if(_args.indexOf('[@|@]') != -1)
  {
    action = _args.substring(0, _args.indexOf('[@|@]'));
    _args = _args.substring(_args.indexOf('[@|@]') + 5);
  }
  //3815debugger;
  if(action.indexOf('-ReloadTextView') != -1)
  {
    // edit mode textview
    var ids = _args.split('@');
    var controlId = ids[0];
    var content = _args.substring(controlId.length+1);
    var hccontainer = document.getElementById('TCC_moretext');
    var tvControl = document.getElementById('TextViewControlContent');
    if(tvControl != null && hccontainer != null)
    {
      //debugger;
      if (tvControl.childNodes.length == 2) //IE
      {
        if(tvControl.childNodes[0].style.height != '30px')
        {
          tvControl.childNodes[0].style.height = '30px';
          tvControl.childNodes[0].style.position = 'absolute';
          tvControl.childNodes[0].style.top = '0px';
        }
        SetOuterHtml(tvControl.childNodes[1], content);
        
        /*if(tvControl.childNodes[1].style.height != '100%')
        {
          tvControl.childNodes[1].style.height = '100%'; //(hccontainer.clientHeight - 75) + 'px';
          tvControl.childNodes[1].style.width = '100%'; //(hccontainer.clientWidth - 5) + 'px';
          tvControl.childNodes[1].style.borderTop = 'solid 30px white';
          tvControl.childNodes[1].style.display = 'block';      
          //m_textViewControlSpanFixedSize = 1;
        }*/
        setTimeout("KGTextTabControl_AdjustTextViewControlSize()",100);

      }
      else if (tvControl.childNodes.length == 4) //FF - counts carriage returns in html as textnodes
      {
        if(tvControl.childNodes[0].style.height != '30px')
        {
          tvControl.childNodes[0].style.height = '30px';
          //tvControl.childNodes[0].style.position = 'absolute';
          //tvControl.childNodes[0].style.top = '0px';
        }
        var container = document.getElementById('TextViewControlContent');

        //tvControl.childNodes[2].outerHTML = content;
        // not support outerHtml
        var tempElement = document.createElement("div");
        tempElement.style.overflow = 'auto';
        
        var start = content.indexOf('<');
        if(start > 0)
          content = content.substring(start);
        var end = content.lastIndexOf('>');
        if(end < content.length -1)
          content = content.substring(0, end + 1);
          
        tempElement.innerHTML = content;
        
        var root = null;
        for(var i=0; i<tempElement.childNodes.length; i++) 
        {
          if(tempElement.childNodes[i].nodeType == 1) 
          {
            root = tempElement.childNodes[i];
            root.style.display = 'block';
            
            if(container != null && root.style.height != '100%')
            {
              root.className = 'KGTextViewControlContainer';
              root.style.height = '100%'; //(hccontainer.clientHeight - 75) + 'px';
              root.style.width = '100%'; //(hccontainer.clientWidth - 5) + 'px';
              root.style.borderTop = 'solid 30px white';      
              
              //m_textViewControlSpanFixedSize = 1;
            }
            break;
          }
        }
        
        if(root)
          tvControl.replaceChild(root, tvControl.childNodes[2]);
          
                  
      }
      
   if(navigator.userAgent.indexOf('Firefox') != -1 || navigator.userAgent.indexOf('Safari') != -1 || navigator.userAgent.indexOf('Opera') != -1)
   {
        var iframeDiv = document.getElementById('TextViewEditFrameDiv');
        if(iframeDiv != null)
          iframeDiv.style.position = 'relative';
   }


      setTimeout("LoadTextView()",300);
      
    }
      KGTextTabControl_HideOrShowLoadingDiv(false);

      m_textFrameCallbackStatus = 'none';
  }
  else
  { // read only text view
    if(_args.indexOf('|<TextViewInfo>|') != -1)
    {
      var values = _args.split('|<TextViewInfo>|');
      // set selected knowde id
      var ids = values[0].split('@');
      // get action key
      var actionKey = ids[0];
      var viewmode = ids[1];
      if(actionKey != 'NewWindowTextView')
      {
        // get old kgId
        var oldFrameKGID = m_strFrameSelectedKGID;
        // set view mode
        m_strFrameViewMode = viewmode;
        // set kgId
        m_strFrameSelectedKGID = ids[2];
        // knowdeID
        m_strFrameSelectedKnowdeDBID = ids[3];
        // use client Id for the moment
        m_strFrameSelectedKnowdeID = ids[4];
        var knowdeContexts = values[0].substring(ids[0].length + ids[1].length + ids[2].length + ids[3].length + ids[4].length + 5).split('||');
        m_strFrameSelectedKnowdeContext = knowdeContexts[0];
        m_strFrameCentreKnowdeContext = knowdeContexts[1];
        
        //alert(m_strFrameSelectedKnowdeID + '|' + m_strFrameSelectedKnowdeContext);
        
        if(oldFrameKGID != m_strFrameSelectedKGID || m_bTextFrameLoadSiblingKnowde == false)
        {
          // kg changed
          ClearTextTabFrame(false);
        }
       
        if(m_strFrameViewMode == "Full" && m_currentTextViewViewMode == m_strFrameViewMode)
        {
          // load all textviews
          HandleTextFrameLoadAll(values[1], values[2], 'TextTabFrame');
        }
        else if(m_strFrameViewMode == "Single" && m_currentTextViewViewMode == m_strFrameViewMode) 
        {
          // load single textview
          var content = values[2];
          var kndText = GetCurrentKnowdeTextForTextView(m_strFrameSelectedKnowdeID);
          if(kndText != '')
          {
            if(content == '')
            {
              content = GetDefaultTextViewContentWithTitle(m_strFrameSelectedKnowdeID, kndText, 1, m_noTextViewFoundContent);
              
              if(GetGlobalHighlightedWhatId() == m_strFrameSelectedKnowdeID
              && globalLastHighlightedWhat != null && globalLastHighlightedWhat.getAttribute('IsUserKI') == 'true'
              && AllowWhatEditOnly == 1 && content.indexOf(m_noTextViewFoundContent) != -1)
                content = content.replace(m_noTextViewFoundContent, m_noTextViewFoundAddYourOwn);

            }else
            {
              content = TrimTickerSpans(content);
              if (content.indexOf(m_textViewTickerSelectionHighlightColor) > -1)
                content = ReturnUnhighlightedTickerText(content);
                

            }
         }

          //m_textTabFrame.contentWindow.document.write("<html><head><base target='_blank'><link href='CSS/KGHelpControl.css' type='text/css' rel='stylesheet'/><link href='CSS/TextViewDocument.css' type='text/css' rel='stylesheet'/></head><body style='overflow:auto;'>"); //class='PersonalisedScrollBar' 
          //m_textTabFrame.contentWindow.document.write(content);
          //m_textTabFrame.contentWindow.document.write("</body></html>");
          
	        if (m_textTabFrame.contentWindow.document.body)
	        {
	            m_textTabFrame.contentWindow.document.body.innerHTML = content;
	        }
	        else
	        {
	            m_textTabFrame.contentWindow.document.write("<html><head><base target='_blank'><link href='CSS/KGHelpControl.css' type='text/css' rel='stylesheet'/><link href='CSS/TextViewDocument.css' type='text/css' rel='stylesheet'/></head><body style='overflow:auto;'>"); //class='PersonalisedScrollBar' 
	            m_textTabFrame.contentWindow.document.write(content);
	            m_textTabFrame.contentWindow.document.write("</body></html>");
	        }          
          
          setTimeout('KGTextTabControl_AdjustTextTabFrameSize()', 100);

         }
      }
      
   }
   

    KGTextTabControl_HideOrShowLoadingDiv(false);

    m_textFrameCallbackStatus = 'none';
  }
}

function KGTextTabControl_CallbackError(_args, _context)
{
  m_textFrameCallbackStatus = 'none';
  
  alert('Callback error on KGTextTabControl. \n\n' + _args);
}

function KGTextTabControl_AdjustTextViewControlSize()
{
   var tvControl = document.getElementById('TextViewControlContent');
   if(tvControl != null && tvControl.childNodes.length == 2)
   {
       tvControl.childNodes[1].className = 'KGTextViewControlContainer';
       tvControl.childNodes[1].style.height = '100%'; //(hccontainer.clientHeight - 75) + 'px';
       tvControl.childNodes[1].style.width = '100%'; //(hccontainer.clientWidth - 5) + 'px';
       tvControl.childNodes[1].style.borderTop = 'solid 30px white';
       tvControl.childNodes[1].style.display = 'block';   
   }
}

function KGTextTabControl_AdjustTextTabFrameSize()
{
   var m_textTabFrame = document.getElementById('TextTabFrame');
   if(m_textTabFrame != null)
   {
       m_textTabFrame.style.pixelHeight = '';
       
       m_textTabFrame.style.width = '100%';
       m_textTabFrame.style.height = '100%';
       m_textTabFrame.style.display = 'block';
       m_textTabFrame.height = '100%';
       m_textTabFrame.width = '100%';
   }
}

function FindSelectedTextFrameKnowdePathContext(_knowdeID)
{
  //debugger;
  var pathContext = '';
  
  if(_knowdeID != null && m_strFrameSelectedKnowdeDBID != '')
  {
    var knowdeID = _knowdeID;
    if(knowdeID < 0)
    {
      // find the knowdeID  instead
      for(var ki = 0; ki < m_FrameKnowdeClientIdsArray.length; ki++)
      {
        if(m_FrameKnowdeClientIdsArray[ki] == knowdeID)
        {
          knowdeID = m_FrameKnowdeIdsArray[ki];
          break;
        }
      }
    }
    
    if(knowdeID > 0 && knowdeID != m_strFrameSelectedKnowdeDBID)
    {
      // basic logic to find possible knowde context and locate the correct text view if knowde is reused
      // might need to be improved later on
      var pathStr = '';
      // in text view assocations:
      // new selected knowde is walked after the previous selected knowde
      var re = new RegExp('(\\[' + m_strFrameSelectedKnowdeDBID + '\\]([^,]+)\\['+knowdeID+'\\])', 'gi');
      // new selected knowde is walked before the previous selected knowde
      var re2 = new RegExp('(\\[' + knowdeID + '\\]([^,]+)\\['+m_strFrameSelectedKnowdeDBID+'\\])', 'gi');
      var matchResult = re.exec(m_FrameKnowdePathString);
      pathStr = m_FrameKnowdePathString;
      if(matchResult == null)
      {
        matchResult = re2.exec(m_FrameKnowdePathString);
      }
      
      if(matchResult != null)
      {
        var foundContext = '';
        var foundIdx = matchResult.index;
        if(foundIdx >= 0)
        {
          var endIdx = pathStr.indexOf(',',foundIdx);
          if(endIdx > 0)
          {
            var pathStr2 = pathStr.substr(0, endIdx);
            var startIdx = pathStr2.lastIndexOf(',');
            if(startIdx == -1)
              foundContext = pathStr2;
            else
              foundContext = pathStr2.substr(startIdx+1);
              
            if(foundContext != '')
            {
              var kidx = foundContext.indexOf('['+knowdeID+']');
              if(kidx != -1)
              {
                foundContext = foundContext.substr(0, kidx + knowdeID.length + 2);
                if(pathStr.indexOf(foundContext + ',') == 0 || pathStr.indexOf(',' + foundContext + ',') != -1)
                  pathContext = foundContext;
              }
            }
          }
        }
      }
    }else if(knowdeID > 0 && knowdeID == m_strFrameSelectedKnowdeDBID)
    {
      pathContext = m_strFrameSelectedKnowdeContext;
    }
    // end if knowdeID > 0
    
  }
  return pathContext;
}

function ChangeSelectedTextFrameKnowde(_selectedKnowdeID, _selectedKnowdePath)
{
  if(m_strFrameSelectedKnowdeID != _selectedKnowdeID)
  {
    if(_selectedKnowdePath == null)
      _selectedKnowdePath = '';
    m_strFrameSelectedKnowdeContext = _selectedKnowdePath;
    m_strFrameSelectedKnowdeID = _selectedKnowdeID;
    return true;
  }
  else
    return false;
}


function ClearTextTabFrame(_clearSelectedValues)
{
  var TextTabFrame = document.getElementById("TextTabFrame");
  if (TextTabFrame.src != null && TextTabFrame.src != "" && TextTabFrame.src != "about:blank")
  {
    /*var parent = TextTabFrame.parentNode;
    
    var newFrame = document.createElement('iframe');
    newFrame.id = "TextTabFrame";
    newFrame.className = "TextTabFrame";
    newFrame.frameBorder = 0;
      
    purge(TextTabFrame);  
    parent.removeChild(TextTabFrame);
    InsertAdjacentElement(parent,"beforeend", newFrame);*/
  }
  else
  {
    // Make sure we clear the contents of the document window
    TextTabFrame.contentWindow.document.write("");
    if ( TextTabFrame.contentWindow.document.body != null
      && TextTabFrame.contentWindow.document.body.innerHTML != null )
    {
      TextTabFrame.contentWindow.document.body.innerHTML = "";
    }
    
    if(navigator.userAgent.toLowerCase().indexOf("firefox") > -1)
      setTimeout("m_textTabFrame.contentWindow.document.close();", 1);
  }
  
  // clear member variables
    //debugger;
  
  m_FrameLoadedKnowdeIdList = new Array();
  m_FrameLoadedKnowdeIdString = '';
  m_FrameUnLoadedKnowdeIdString = '';

  // knowde and client knowde list
  m_FrameKnowdeIdsArray = new Array();
  m_FrameKnowdeClientIdsArray = new Array();

  m_FrameDivIDArray = new Array();
  m_FrameDivPathArray = new Array();
  m_FrameDivHeightArray = new Array();
  m_FrameKnowdePathString = '';
  
  if(_clearSelectedValues == null || _clearSelectedValues == true)
  {
    m_strFrameSelectedKGID = '';
    m_strFrameSelectedKnowdeID = '';
    m_strFrameSelectedKnowdeDBID = '';
    m_strFrameSelectedKnowdeContext = '';
    m_strFrameCentreKnowdeContext = '';
    m_bTextFrameLoadSiblingKnowde = false;
  }
  
  m_textFrameScrollTimeOut = null;
}
 
 
 function HandleTextFrameLoadAll(_knowdeSequenceInfo, _loadedContentList)
{
  //debugger;

  if(m_bTextFrameLoadSiblingKnowde == false)
  {
    m_FrameLoadedKnowdeIdList = new Array();
    m_FrameLoadedKnowdeIdString = '';
  
    m_FrameKnowdeIdsArray = new Array();
    m_FrameKnowdeClientIdsArray = new Array();
    
    m_FrameKnowdePathString = '';
    
    var frameDivHtml = '';
    
    // loop through all the knowdes m_strSelectedKnowdeID is the currently selecte knowde
    // knowdes above and below will be loaded in top and bottom iframes
    // don't use split incase the knowde title contains character that is used as our seperator
    var foundCurrentKnowde = 0;
    var kidx = _knowdeSequenceInfo.indexOf('(kid=');
    while(kidx >= 0)
    {
      var kidx2 = _knowdeSequenceInfo.indexOf('|ckid=', kidx+1);
      if(kidx2 > kidx)
      {
        var knowdeId = _knowdeSequenceInfo.substr(kidx+5, kidx2-(kidx+5));
        var kidx3 = _knowdeSequenceInfo.indexOf('|path=', kidx2+1);
        if(kidx3 > kidx2)
        {
          var clientKnowdeId = _knowdeSequenceInfo.substr(kidx2+6, kidx3-(kidx2+6));
          
          // store the knowde and client id mapping
          m_FrameKnowdeIdsArray.push(knowdeId);
          m_FrameKnowdeClientIdsArray.push(clientKnowdeId);
          
          var kidx4 = _knowdeSequenceInfo.indexOf('|title=', kidx3+1);
          if(kidx4 > kidx3)
          {
            var pathContext = _knowdeSequenceInfo.substr(kidx3+6, kidx4-(kidx3+6));
            kidx = _knowdeSequenceInfo.indexOf(')(kid=', kidx4+1);
            var knowdeTitle = '';
            if(kidx > kidx4)
            {
              knowdeTitle = _knowdeSequenceInfo.substr(kidx4+7, kidx-(kidx4+7));
              kidx = kidx + 1; // because we are searching for )( instead of just (
            }else if(kidx == -1)
            {
              knowdeTitle = _knowdeSequenceInfo.substr(kidx4+7, _knowdeSequenceInfo.length-1-(kidx4+7));
            }
            
            // now create div and load to the content
            var frame = m_textTabFrame;
             
             if(frame != null)
             {
               var loaded = 0;
               var sidx = _loadedContentList.indexOf('<HKTextView' + clientKnowdeId + '>');
               var sidx2 = _loadedContentList.indexOf('</HKTextView>', sidx+1);
               var content = '';
               if(sidx != -1 && sidx2 != -1)
               {
                  loaded = 1;
                  content = _loadedContentList.substr(sidx+11+clientKnowdeId.length+1,sidx2-(sidx+11+clientKnowdeId.length+1));
                  var kid = clientKnowdeId;
                 
                  m_FrameLoadedKnowdeIdList.push(kid);
                  m_FrameLoadedKnowdeIdString += kid + ','
                 
                  var bidx = content.toLowerCase().indexOf('<body');
                  var bidx2 = content.indexOf('>');
                  var bidx3 = content.toLowerCase().indexOf('</body>');
                  if(bidx != -1 && bidx2 > bidx && bidx3 > bidx2)
                    content = content.substr(bidx2+1, bidx3-(bidx2+1));
        
                  if(content == '')
                  {
                    content = GetDefaultTextViewContentWithTitle(clientKnowdeId, knowdeTitle, 1, m_noTextViewFoundContent);
                  }else
                  {
                    content = TrimTickerSpans(content);
                    if (content.indexOf(m_textViewTickerSelectionHighlightColor) > -1)
                      content = ReturnUnhighlightedTickerText(content);
                      
                    // check whether it has an existing title, if not, add the title manually
//                    if(CheckTextViewHasTitle(clientKnowdeId, knowdeTitle, content) == false)
//                      content = WrapTextViewContentWithTitle(clientKnowdeId, knowdeTitle, content);
                  }
                                    
               }else
               {
                 loaded = 0;
                 // text view is not loaded yet
                 content = GetDefaultTextViewContentWithTitle(clientKnowdeId, knowdeTitle, 1, m_notLoadedText);
                 m_FrameUnLoadedKnowdeIdString += clientKnowdeId + ','
               }
               
              if((m_strFrameSelectedKnowdeID == knowdeId || m_strFrameSelectedKnowdeID == clientKnowdeId)
              && m_strFrameSelectedKnowdeContext == '')
              {
                  m_strFrameSelectedKnowdeContext = pathContext;
              }
               
               //for scrolling position detection debug only//
               //content = pathContext + '<br>' + content; 
              
               m_FrameKnowdePathString += pathContext + ',';
               
                    var divHtml = "<div id='" + pathContext + "' kid='" + clientKnowdeId + "' title='" + knowdeTitle + "' isLoaded='" + loaded + "' width='100%'>";
                    //if (content.indexOf(m_textViewTickerSelectionHighlightColor) > -1)
                      //content = ReturnUnhighlightedTickerText(content);
                    
                    // directly add content can't deal with not proper formatted HTML
                    // like  missing ticker span close tag etc and then cause iframe's innerHTML 
                    // to be auto corrected later on by added a </span> in the end 
                    // so causing problem because childNodes is not right anymore
                    //divHtml += content; 
                    var tempDiv = document.createElement("div");
                    tempDiv.innerHTML = content; // the content will be auto corrected and guanrantee the ifram only contains divs as first level child nodes
                    divHtml += tempDiv.innerHTML; 
                    divHtml += "</div>";
                      
                    frameDivHtml += divHtml;
                 
             }
            
          }
        }
      }
    }// end while
    
    m_textTabFrame.contentWindow.document.write("<html><head><base target='_blank'><link href='CSS/KGHelpControl.css' type='text/css' rel='stylesheet'/><link href='CSS/TextViewDocument.css' type='text/css' rel='stylesheet'/></head><body style='overflow:auto;' onscroll='parent.TextFrameScrollTimeOut(\"TextTabFrame\")'>"); //class='PersonalisedScrollBar' 
    m_textTabFrame.contentWindow.document.write(frameDivHtml);
    m_textTabFrame.contentWindow.document.write("</body></html>");
     
  } // end if
  else
  {
    
    // need to find out where the knowde is
    var knowdeFrame = '';
      
    // patial load text views
    if(_loadedContentList && _loadedContentList != ''
      && m_textTabFrame != null)
    {
       // loop through each textview content
        var sidx = _loadedContentList.indexOf('<HKTextView');
        var sidx2 = _loadedContentList.indexOf('>', sidx);
        var sidx3 = _loadedContentList.indexOf('</HKTextView>', sidx2);
        while(sidx != -1 && sidx2 != -1 && sidx3 != -1)
        {
          var content = _loadedContentList.substr(sidx2+1, sidx3-(sidx2+1));
          var kid = _loadedContentList.substr(sidx+11,sidx2-(sidx+11));
          
          if((m_FrameLoadedKnowdeIdString.indexOf(kid+',') != 0)
          && (m_FrameLoadedKnowdeIdString.indexOf(','+kid+',') == -1))
          {
            m_FrameLoadedKnowdeIdList.push(kid);
            m_FrameLoadedKnowdeIdString += kid + ',';
            
            // remove from unloaded list
            if(m_FrameUnLoadedKnowdeIdString.indexOf(kid+',') == 0)
              m_FrameUnLoadedKnowdeIdString = m_FrameUnLoadedKnowdeIdString.substring(kid.length+1);
            else
              m_FrameUnLoadedKnowdeIdString = m_FrameUnLoadedKnowdeIdString.replace(','+kid+',', ',');
              
            // load all the unloaded textviews for this knowde to the given content
            var bidx = content.toLowerCase().indexOf('<body');
            var bidx2 = content.indexOf('>');
            var bidx3 = content.toLowerCase().indexOf('</body>');
            if(bidx != -1 && bidx2 > bidx && bidx3 > bidx2)
               content = content.substr(bidx2+1, bidx3-(bidx2+1));
               
            var method = function(el){if(el.getAttribute('kid') == kid) return true; return false;};
            var frameDivs = YAHOO.util.Dom.getChildrenBy(m_textTabFrame.contentWindow.document.body,method);   
            for(var iCounter = 0; iCounter < frameDivs.length; iCounter++)
            {
                  var childDiv = frameDivs[iCounter];
                  
                  if(content == '')
                      content = childDiv.innerHTML.replace(m_notLoadedText, m_noTextViewFoundContent);
                  else
                  {
                    content = TrimTickerSpans(content);
                    if (content.indexOf(m_textViewTickerSelectionHighlightColor) > -1)
                      content = ReturnUnhighlightedTickerText(content);
                      
                    //for scrolling position detection debug only//
                    //content = childDiv.id + '<br>' + content; 
                    
                    // check whether it has an existing title, if not, add the title manually
                    var ckid = childDiv.getAttribute('kid');
                    var ktitle = childDiv.getAttribute('title');
//                    if(CheckTextViewHasTitle(ckid, ktitle, content) == false)
//                      content = WrapTextViewContentWithTitle(ckid, ktitle, content);
                  }
                  

                  if(childDiv != null && childDiv.getAttribute('kid') == kid && (childDiv.getAttribute('isLoaded') == 0 || childDiv.getAttribute('isLoaded') == '0'))
                  {
                    childDiv.innerHTML = content;
                    childDiv.setAttribute('isLoaded', 1);
                  }
             }      

            
          }
          
                         
            _loadedContentList = _loadedContentList.substr(sidx3+13);
            sidx = _loadedContentList.indexOf('<HKTextView');
            sidx2 = _loadedContentList.indexOf('>', sidx);
            sidx3 = _loadedContentList.indexOf('</HKTextView>', sidx2);
          
        }    // end while
      
    }
  }
  
  window.setTimeout("SetupTextFrameKnowdeTextViewDivs()",200);
}

function SetupTextFrameKnowdeTextViewDivs()
{
  //debugger;
  m_textTabFrame = document.getElementById("TextTabFrame");
  var adiv = null;
  
  if(m_textTabFrame != null)
    adiv = m_textTabFrame.contentWindow.document.body;

  m_FrameDivIDArray = new Array();
  m_FrameDivPathArray = new Array();
  m_FrameDivHeightArray = new Array();
  // m_FrameKnowdePathString  = '';

  var pos = 0;
  if(m_textTabFrame != null && adiv != null)
  {
     if(m_strFrameSelectedKnowdeContext == '' && m_strFrameSelectedKnowdeID != '')
     {
        var method = function(el){if(el.getAttribute('kid') == m_strFrameSelectedKnowdeID) return true; return false;};
        //var frameDivs = YAHOO.util.Dom.getElementsBy(method,null,adiv);  
        var frameDivs = YAHOO.util.Dom.getChildrenBy(adiv,method);   
        if(frameDivs.length > 0)
          m_strFrameSelectedKnowdeContext = frameDivs[0].id;
     }
                
        if(m_strFrameCentreKnowdeContext != '')
        {
          var method = function(el){if(el.id == m_strFrameCentreKnowdeContext) return true; return false;};
          //var frameDivs = YAHOO.util.Dom.getElementsBy(method,null,adiv);  
          var frameDivs = YAHOO.util.Dom.getChildrenBy(adiv,method);   
          if(frameDivs.length > 0)
          {
            // make sure scroll to this position
            m_bTextFrameManualScroll = true;
            
            var scrollTopValue = frameDivs[0].offsetTop - m_textTabFrame.offsetHeight/2;
            //scrollTopValue = scrollTopValue - m_frameScrollTopOffSet;
            if(scrollTopValue < 0)
              scrollTopValue = 0;
            adiv.scrollTop  = scrollTopValue;
          }
          
        }
        
        if(m_strFrameSelectedKnowdeContext != '')
        { 
          if(m_previousHighLightedPath != '')
          {
              // unhighlight
            var method = function(el){if(el.id == m_previousHighLightedPath) return true; return false;};
            //var frameDivs = YAHOO.util.Dom.getElementsBy(method,null,adiv);  
            var frameDivs = YAHOO.util.Dom.getChildrenBy(adiv,method);   
            if(frameDivs.length > 0)
            {
              //frameDivs[0].style.backgroundColor = 'white';
              frameDivs[0].style.borderLeft = 'none';
              frameDivs[0].style.paddingLeft = '0px';
              frameDivs[0].style.marginLeft = '0px';
            }
           
          }
          
          // highlight
          var method = function(el){if(el.id == m_strFrameSelectedKnowdeContext) return true; return false;};
          //var frameDivs = YAHOO.util.Dom.getElementsBy(method,null,adiv);  
          var frameDivs = YAHOO.util.Dom.getChildrenBy(adiv,method);   
          if(frameDivs.length > 0)
          {
            if(m_strFrameCentreKnowdeContext == '')
            {
              // make sure scroll to this position
              // m_bTextFrameManualScroll = true;
              var scrollTopValue = frameDivs[0].offsetTop - (m_frameScrollTopOffSet + 20);
              if(scrollTopValue < 0)
                scrollTopValue = 0;
              m_textFrameScrollMoreOnTopTimeOut = window.setTimeout("TextScrollMoreFromTop('TextTabFrame'," + scrollTopValue + ", 0)", m_textFrameScrollDelay);
              //adiv.scrollTop  = scrollTopValue;
            }
            
            // now get rid of the empty <P> tags in the end which makes the next div overlay a bit with the current div
            var content = frameDivs[0].innerHTML;
            content = content.replace(/(<p\/>|<p><\/p>|<p \/>|<p><br \/><\/p>|<p><br\/><\/p>)+$/i,'');//remove trailing empty paragraph
            content = content.replace(/(<p\/>|<p><\/p>|<p \/>|<p><br \/><\/p>|<p><br\/><\/p>)<\/div>+$/i,'</div>');//remove trailing empty paragraph
            frameDivs[0].innerHTML = content;

            frameDivs[0].style.borderLeft = m_textFrameHighlightBorderLeftStyle;
            frameDivs[0].style.paddingLeft = m_textFrameHighlightBorderLeftPadding + 'px';
            frameDivs[0].style.marginLeft = '-' + m_textFrameHighlightBorderLeftPadding + 'px';
            
           m_previousHighLightedPath = frameDivs[0].id;
         }
          
      }        
    
  }
  
    setTimeout('KGTextTabControl_AdjustTextTabFrameSize()', 100);
}


function ChangeSelectedTextTabFrameKnowde(_selectedKnowdeID, _selectedKnowdePath)
{
  if(m_strFrameSelectedKnowdeID != _selectedKnowdeID)
  {
    if(_selectedKnowdePath == null)
      _selectedKnowdePath = '';
    m_strFrameSelectedKnowdeContext = _selectedKnowdePath;
    m_strFrameSelectedKnowdeID = _selectedKnowdeID;
    return true;
  }
  else
    return false;
}

function GetTextViewCallBackArgs(_kgId)
{
  m_textTabFrame = document.getElementById("TextTabFrame");
  var kgid = Active_KGID;
  if(_kgId != null && _kgId > 0)
    kgid = _kgId;
  var args = "|KGId=" + kgid + "|ViewMode=" + m_currentTextViewViewMode;
  
  // if the docVersion is not null add it to the callback args
  if (m_textViewDocVersion != null)
    args += "|DocumentVersion=" + m_textViewDocVersion;
   
  var loadamount = m_textTabFrame.offsetHeight/40/2;
    if(m_textViewPreLoadAmount > loadamount)
      loadamount = m_textViewPreLoadAmount;
  args += "|PreLoadAmount=" + loadamount;
  
  if(m_bTextFrameLoadSiblingKnowde == true)
  {
    args += "|LoadSiblingKnowde=true";
    var toLoadDivs = '';
    var knowdeContext = m_strFrameSelectedKnowdeContext;
    
    toLoadDivs = GetPreLoadDivsForTextFrameSelectedKnowde(m_tickerKnowdeID, knowdeContext, loadamount);       
    
    args += '|KnowdeId=' + m_tickerKnowdeID + '|KnowdePathContext=' + knowdeContext + '|KnowdeIdList=' + toLoadDivs;;
    
    if(toLoadDivs == '')
      args += "|KnowdeLoaded=true";
    else
      args += "|KnowdeLoaded=false";
  }else
  {
    // assume each text view has minimum 40px height
    args += "|KnowdeLoaded=false";
  }
  
  return args;
}

function FindSelectedTextViewFrameKnowdePathContext(_knowdeID)
{
  //debugger;
  var pathContext = '';
  
  if(_knowdeID != null && m_strFrameSelectedKnowdeDBID != '')
  {
    var knowdeID = _knowdeID;
    if(knowdeID < 0)
    {
      // find the knowdeID  instead
      for(var ki = 0; ki < m_FrameKnowdeClientIdsArray.length; ki++)
      {
        if(m_FrameKnowdeClientIdsArray[ki] == knowdeID)
        {
          knowdeID = m_FrameKnowdeIdsArray[ki];
          break;
        }
      }
    }
    
    if(knowdeID > 0 && knowdeID != m_strFrameSelectedKnowdeDBID)
    {
      // basic logic to find possible knowde context and locate the correct text view if knowde is reused
      // might need to be improved later on
      var pathStr = '';
      // in text view assocations:
      // new selected knowde is walked after the previous selected knowde
      var re = new RegExp('(\\[' + m_strFrameSelectedKnowdeDBID + '\\]([^,]+)\\['+knowdeID+'\\])', 'gi');
      // new selected knowde is walked before the previous selected knowde
      var re2 = new RegExp('(\\[' + knowdeID + '\\]([^,]+)\\['+m_strFrameSelectedKnowdeDBID+'\\])', 'gi');
      var matchResult = re.exec(m_FrameKnowdePathString);
      pathStr = m_FrameKnowdePathString;
      if(matchResult == null)
      {
        matchResult = re2.exec(m_FrameKnowdePathString);
      }
      
      if(matchResult != null)
      {
        var foundContext = '';
        var foundIdx = matchResult.index;
        if(foundIdx >= 0)
        {
          var endIdx = pathStr.indexOf(',',foundIdx);
          if(endIdx > 0)
          {
            var pathStr2 = pathStr.substr(0, endIdx);
            var startIdx = pathStr2.lastIndexOf(',');
            if(startIdx == -1)
              foundContext = pathStr2;
            else
              foundContext = pathStr2.substr(startIdx+1);
              
            if(foundContext != '')
            {
              var kidx = foundContext.indexOf('['+knowdeID+']');
              if(kidx != -1)
              {
                foundContext = foundContext.substr(0, kidx + knowdeID.length + 2);
                if(pathStr.indexOf(foundContext + ',') == 0 || pathStr.indexOf(',' + foundContext + ',') != -1)
                  pathContext = foundContext;
              }
            }
          }
        }
      }
    }else if(knowdeID > 0 && knowdeID == m_strFrameSelectedKnowdeDBID)
    {
      pathContext = m_strFrameSelectedKnowdeContext;
    }
    // end if knowdeID > 0
    
  }
  return pathContext;
}

function GetPreLoadDivsForTextFrameSelectedKnowde(_knowdeId, _knowdePath, _loadAmount)
{
  // when a knowde is selected in the mapview, find out what knowde text views need to be loaded around it
  var toLoadDivs = '';
  _loadAmount = Math.round(_loadAmount);
  
  if(_knowdePath == '')
  {
      // get the first occurrance of the knowde as default 
      var adiv = m_textTabFrame.contentWindow.document.body;
      
      var method = function(el){if(el.getAttribute('kid') == _knowdeId) return true; return false;};
      //var frameDivs = YAHOO.util.Dom.getElementsBy(method,null,adiv); 
      var frameDivs = YAHOO.util.Dom.getChildrenBy(adiv,method);
         
      if(frameDivs.length > 0)
         _knowdePath = frameDivs[0].id;
  }
    
  if(m_FrameLoadedKnowdeIdString.indexOf(_knowdeId + ',') != 0 &&  m_FrameLoadedKnowdeIdString.indexOf(',' + _knowdeId + ',') == -1)
    toLoadDivs = _knowdeId + ',';
    
  if(_knowdePath != '')
  {
    if(_knowdeId == m_strFrameSelectedKnowdeID)
      m_strFrameSelectedKnowdeContext = _knowdePath;
      
    // unique context found, now need to find out knowdes around the given knowde path
    var pathArray = m_textTabFrame.contentWindow.document.body.childNodes;
    
    var idx = -1;
    for(var icount = 0; icount < pathArray.length; icount++)
    {
      var childDiv = pathArray[icount];
      if(childDiv.id == _knowdePath)
      {
        idx = icount;
        break;
      }
    }
    if(idx >= 0)
    {
      var startIdx = idx - _loadAmount;
      var endIdx = idx + _loadAmount;
      if(startIdx < 0)
        endIdx -= startIdx;
      if(endIdx >= pathArray.length)
        startIdx -= (pathArray.length-1);
      if(startIdx < 0)
        startIdx = 0;
      if(endIdx >= pathArray.length)
        endIdx = pathArray.length - 1;
        
      for(var icount = startIdx; icount <= endIdx; icount++)
      {
        if(pathArray[icount])
        {
          if(m_FrameLoadedKnowdeIdString.indexOf(pathArray[icount].getAttribute('kid') + ',') != 0 &&  m_FrameLoadedKnowdeIdString.indexOf(',' + pathArray[icount].getAttribute('kid') + ',') == -1)
            toLoadDivs += pathArray[icount].getAttribute('kid') + ',';
        }
      }
    }
    
  }
  
  
  return toLoadDivs;
}


function SwitchTextViewViewMode(_newMode)
{
  if (_newMode == m_currentTextViewViewMode)
    return;
  
  if(m_textFrameCallbackStatus == 'trigger') // callback in process
  {
    alert('Text is still loading, please try later.');
    return;
  }
    
  var modeSwitchBtn = document.getElementById('TextViewModeSwitch');
  var previewSwitchBtn = document.getElementById('TextViewPreviewSwitch');
  if(_newMode == null)
  {
    if(m_currentTextViewViewMode == "Single")
    {
      // to full text view mode
      m_textViewViewModeChanged = true;
      m_currentTextViewViewMode = "Full";
      m_bTextFrameLoadSiblingKnowde = false;
      // load full text view
      var currentKnowdeID = m_strFrameSelectedKnowdeID;
      SetSessionProperty('TickerKnowde', currentKnowdeID);
      m_tickerKnowdeID = currentKnowdeID;
      DisplayTextViewInTab("TextForSpecifiedKnowde"); 
      
      if(modeSwitchBtn != null)
      {
        SetInnerText(modeSwitchBtn, "Back to Text Component"); 
      }
      
      if(previewSwitchBtn != null)
      {
        SetInnerText(previewSwitchBtn, "Back to Text Edit");
      }
    }else if(m_currentTextViewViewMode == "Full")
    {
      // to single text view mode
      //m_textViewViewModeChanged = true;
      m_currentTextViewViewMode = "Single";
      m_bTextFrameLoadSiblingKnowde = false;
      
      // get the existing seletected knowd div
      var divHtml = '';
      var currentframe = document.getElementById("TextTabFrame");
      if(currentframe != null)
      {
        var method = function(el){if(el.getAttribute('kid') == m_strFrameSelectedKnowdeID) return true; return false;};
        var frameDivs = YAHOO.util.Dom.getChildrenBy(currentframe.contentWindow.document.body,method);   
        if(frameDivs.length > 0)
        {
          var childDiv = frameDivs[0];
          divHtml = childDiv.innerHTML;
        }
      }

      // clear frame
      ClearTextTabFrame(false);
      
      // set variables like we actually done a callback done
      m_strFrameViewMode = "Single";
      // m_strFrameSelectedKGID, m_strFrameSelectedKnowdeDBID, m_strFrameSelectedKnowdeID remain unchanged
      m_strFrameSelectedKnowdeContext = "";
      m_strFrameCentreKnowdeContext = "";
      
      // load single text view
      if(currentframe != null)
      {
         if(GetGlobalHighlightedWhatId() == m_strFrameSelectedKnowdeID
         && globalLastHighlightedWhat != null && globalLastHighlightedWhat.getAttribute('IsUserKI') == 'true'
         && AllowWhatEditOnly == 1 && content.indexOf(m_noTextViewFoundContent) != -1)
         divHtml = divHtml.replace(m_noTextViewFoundContent, m_noTextViewFoundAddYourOwn);

          currentframe.contentWindow.document.write("<html><head><base target='_blank'><link href='CSS/KGHelpControl.css' type='text/css' rel='stylesheet'/><link href='CSS/TextViewDocument.css' type='text/css' rel='stylesheet'/></head><body style='overflow:auto;'>"); //class='PersonalisedScrollBar' 
          currentframe.contentWindow.document.write(divHtml);
          currentframe.contentWindow.document.write("</body></html>");
          
          setTimeout('KGTextTabControl_AdjustTextTabFrameSize()', 100);
      }
                      
      
      if(modeSwitchBtn != null)
      {
        SetInnerText(modeSwitchBtn, "Click to view Full Document"); 
      }
      
      if(previewSwitchBtn != null)
      {
        SetInnerText(previewSwitchBtn, "Click to preview Full Document");
      }
    }
  }else
  {
    if(_newMode == "Full" && m_currentTextViewViewMode != "Full")
    {
      // to full text view mode
      m_currentTextViewViewMode = "Full";
      
      if(modeSwitchBtn != null)
      {
        SetInnerText(modeSwitchBtn, "Back to Text Component"); 
      }
      
      if(previewSwitchBtn != null)
      {
        SetInnerText(previewSwitchBtn, "Back to Text Edit");
      }
    }else if(_newMode == "Single" && m_currentTextViewViewMode != "Single")
    {
      // to single text view mode
      m_currentTextViewViewMode = "Single";
      
      if(modeSwitchBtn != null)
      {
        SetInnerText(modeSwitchBtn, "Click to view Full Document"); 
      }
      
      if(previewSwitchBtn != null)
      {
        SetInnerText(previewSwitchBtn, "Click to preview Full Document");
      }
    }
  }
}

function KGTextTabControl_HideOrShowTextViewOptionDiv(_showOption)
{
//debugger;
  var optionDiv = document.getElementById('TextViewModeSwitch');
  //m_textTabFrame = document.getElementById("TextTabFrame");
  if(_showOption != null && _showOption == true)
  {
    if(optionDiv != null)
      optionDiv.style.display = 'block';
  }
  else
  {
    if(optionDiv != null)
      optionDiv.style.display = 'none';
  }
  
}


function KGTextTabControl_HideOrShowLoadingDiv_Wrapped(_divId, _show, _message)
{
  if(m_textFrameLoadingDivTimeOut != null)
  {
    clearTimeout(m_textFrameLoadingDivTimeOut);
    m_textFrameLoadingDivTimeOut = null;
  }
  
   var div = null; 
   
   if(_divId != null && _divId != '')
      div = document.getElementById(_divId);
   if(_message == null)
    _message = 'Loading...';
    
   if(_show != null && _show == true && (_message != 'Saving...' && m_textFrameCallbackStatus != 'trigger'))
   {
    // callback done has finished before the trigger time out to show the loading div, 
    // so don't need to show it anymore
    return;
   }
    
   if (div != null)
   {
    if(_show != null && _show == true)
    {
      if(div.style.display != 'block')
      {
        div.innerHTML = "<img src=\"Images/loadingbar.gif\" /> " + _message; // m_LoadingMessage;
        div.style.display = 'block';
  
        if(navigator.userAgent.indexOf('Firefox') != -1 || navigator.userAgent.indexOf('Safari') != -1 || navigator.userAgent.indexOf('Opera') != -1)
        {
          div.style.width = '100%';
        }
      }
    }else if(div.style.display != 'none')
    {
      div.style.display = 'none';
      div.innerHTML = '';
    }
   }
   
}

function PreviewFullTextView()
{
  if(m_textFrameCallbackStatus == 'trigger') // callback in process
  {
    alert('Text is still loading, please try later.');
    return;
  }
  // save text view
  SaveCurrentlyEditingTextView(false);
  
  // hide the button
  if(m_currentTextViewViewMode == "Single")
  {
    // set the view mode to full document
    SwitchTextViewViewMode("Full");
    m_textViewViewModeChanged = true;
    DisplayTextViewInTab('TextView', '', 'true', Active_KGID);
  }else
  {
    // back to single mode text edit 
    SwitchTextViewViewMode("Single");
    
    DisplayTextViewInTab("KnowdeSelected-ReloadTextView", globalSplitterSetting, "true"); 
    globalLastTickerAction = "KnowdeSelected-ReloadTextView" + m_tickerKnowdeID;
  }
}


function TextFrameScrollTimeOut(_frameID)
{
  if(m_textFrameScrollTimeOut != null)
  {
      clearTimeout(m_textFrameScrollTimeOut);
      m_textFrameScrollTimeOut =  null;
  }
  if(m_bTextFrameManualScroll == true)
  {
    m_bTextFrameManualScroll = false;
    return;
  }
  // if in full text view mode and has unloaded textviews, then trigger partial loading
  if(m_FrameUnLoadedKnowdeIdString != '' && m_strFrameViewMode == "Full")
  {
      m_textFrameScrollTimeOut = setTimeout('HandleTextFrameScroll()', 2000);
  }
}

function HandleTextFrameScroll(_frameID)
{
   
  //debugger;
  
  if(m_textFrameScrollTimeOut != null)
  {
      clearTimeout(m_textFrameScrollTimeOut);
      m_textFrameScrollTimeOut =  null;
  }
  
    
  //debugger;
  var frameType = '';
  m_textTabFrame = document.getElementById("TextTabFrame");
  var textFrameDiv = null;
  
  // get frame info and decide which frame to do the partial loading
  var textFrameWidth = -1;
  if(m_textTabFrame != null)
  {
    textFrameDiv = m_textTabFrame.contentWindow.document.body;
    textFrameWidth = m_textTabFrame.offsetWidth;;
  }
  
  var frameDiv = null;
  var frame = null;
  if(_frameID != null && _frameID != '')
    frame = document.getElementById(_frameID);
    
  if(frame == null)
  {
    if(textFrameDiv != null && textFrameWidth != -1)
    {
      frameType = 'Popup';
      frameDiv = textFrameDiv;
      frame = m_textTabFrame;  
    }
  }else
  {
    frameDiv = frame.contentWindow.document.body;
  }
    
  if(frameDiv != null)
  {
    // clear the knowde hover scroll timeout because user now manually scrolling
    clearTimeout(m_textFrameScrollMoreOnTopTimeOut);

    var scrollTop = frameDiv.scrollTop;
    var visibleStartPosition = scrollTop;
    var visibleEndPosition = scrollTop + frame.offsetHeight;
    var centrePosition = visibleStartPosition + frame.offsetHeight/2;
    
    // also preload stuff that fall into 100px ouside the visible range
    if(visibleStartPosition - 60 <= 0)
      visibleStartPosition = 0
    else
      visibleStartPosition -= 60;
    
    if(visibleEndPosition + 60 >= frameDiv.scrollHeight + 30)
      visibleEndPosition = frameDiv.scrollHeight + 30
    else
      visibleEndPosition += 60;
        
    // check which divs are in visible area
    var visibleDivs = '';
    var toLoadDivs = '';
    var centreID = '';
    var centrePath = '';
      // might need to load top frame contents
      var pos = 0;
            
      /*for(var dividx = 0; dividx < m_FrameDivIDArray.length; dividx++)
      {
        if((pos+ parseInt(m_FrameDivHeightArray[dividx]) >= visibleStartPosition && pos <= visibleEndPosition))
        {
          visibleDivs += m_FrameDivIDArray[dividx] + ',';
          if(pos <= centrePosition && pos+ parseInt(m_FrameDivHeightArray[dividx]) >= centrePosition)
          {
            centreID = m_FrameDivIDArray[dividx];
            centrePath = m_FrameDivPathArray[dividx];
          }
          // check whether need to load this div
          if((m_FrameUnLoadedKnowdeIdString.indexOf(m_FrameDivIDArray[dividx]+',') == 0)
          || (m_FrameUnLoadedKnowdeIdString.indexOf(','+m_FrameDivIDArray[dividx]+',') != -1))
          {
            toLoadDivs += m_FrameDivIDArray[dividx] + ',';
          }
        }
        pos += parseInt(m_FrameDivHeightArray[dividx]);
        pos += m_frameDivGapHeight;
      }*/
      
      for(var dividx = 0; dividx < frame.contentWindow.document.body.childNodes.length; dividx++)
      {
        var childDiv = frame.contentWindow.document.body.childNodes[dividx];
        
        if((childDiv.offsetHeight + childDiv.offsetTop >= visibleStartPosition && childDiv.offsetTop <= visibleEndPosition))
        {
          visibleDivs += childDiv.getAttribute('kid') + ',';
          if(childDiv.offsetTop <= centrePosition && childDiv.offsetTop + childDiv.offsetHeight >= centrePosition)
          {
            centreID = childDiv.getAttribute('kid');
            centrePath = childDiv.id;
          }else if(childDiv.offsetTop > centrePosition && centreID == '')
          {
            // the middle point fall into the gap between two divs, sometimes there is a 19px gap between
            centreID = childDiv.getAttribute('kid');
            centrePath = childDiv.id;
          }
          // check whether need to load this div
          if((m_FrameUnLoadedKnowdeIdString.indexOf(childDiv.getAttribute('kid')+',') == 0)
          || (m_FrameUnLoadedKnowdeIdString.indexOf(','+childDiv.getAttribute('kid')+',') != -1))
          {
            toLoadDivs += childDiv.getAttribute('kid') + ',';
          }
        }else if(centreID != '')
          break;
      }

    //alert(centreID + '|' + centrePath + '#' + visibleDivs);
    // store the centre knowde path context
    m_strFrameCentreKnowdeContext = centrePath;
    //alert('Center: ' + centrePath);
        
    if(toLoadDivs != '')
    {
      if(centreID == '' || centrePath == '')
      {
        alert('Invalid centre ID and Path.');
        //debugger;
      }
      else
      {
        m_bTextFrameLoadSiblingKnowde = true;
        // trigger callback to partial load
        var args = "|KGId=" + m_strFrameSelectedKGID + '|KnowdeId=' + m_strFrameSelectedKnowdeID + '|KnowdePathContext=' + m_strFrameSelectedKnowdeContext + '|KnowdeTitle=|CentreKnowdePathContext=' + centrePath + '|KnowdeIdList=' + toLoadDivs;
        args += "|LoadSiblingKnowde=true";
        args += "|KnowdeLoaded=false";
        args += "|LoadTrigger=Scrolling";
        args += "|ViewMode=Full";
        
        if(m_textFrameScrollTimeOut != null) // been scroll again
        {
            //clearTimeout(m_textFrameScrollTimeOut);
            // m_textFrameScrollTimeOut =  null;
        }else
          KGTextTabControl_CallbackTrigger('TextView', args); //, globalHelpTopicParams); //We're no longer using the xml help
      }
    }
    
  }
}

function TextScrollMoreFromTop(_target, _scrollTop, _amount)
{
  //debugger;
  var div = null;
  m_textTabFrame = document.getElementById("TextTabFrame");
  var adiv = null;
  
  if(m_textTabFrame != null)
    adiv = m_textTabFrame.contentWindow.document.body;

  if(_target == 'TextTabFrame')
  {
    clearTimeout(m_textFrameScrollMoreOnTopTimeOut);
    m_textFrameScrollMoreOnTopTimeOut = null;
    div = adiv;
  } 
  //debugger;
  if(div != null)
  {
    //alert(_scrollTop + '|' + _amount + '|' + div.scrollTop);

    if(_scrollTop < 0)
      _scrollTop = 0;
      
    if(_amount <= 0)
    {
      // calculate scroll amount
      var diff = Math.abs(_scrollTop - div.scrollTop);
      if(diff == 0)
        return;
      else if(diff < 100)
      {
        _amount = Math.ceil(diff/2); // minum 2 times
      }
      else if(diff <= 500)
        _amount = 50;
      else
      {
        _amount = Math.ceil(diff/10); // maximum do it 10 times
      }
      if(_amount <= 0)
        _amount = 10;
    }
    
      var scrollTo = div.scrollTop;
      if(div.scrollTop > _scrollTop)
      {
        scrollTo -=  _amount;
        if(scrollTo < _scrollTop)
          scrollTo = _scrollTop;
      }else if(div.scrollTop < _scrollTop)
      {
        scrollTo += _amount;
        if(scrollTo > _scrollTop)
          scrollTo = _scrollTop;
      }
      // now scroll to the position
      m_bTextFrameManualScroll = true;
      div.scrollTop = scrollTo;
      // if we have scroll to the desire location, and also haven't reach the end 
      if(div.scrollTop != _scrollTop && div.scrollTop == scrollTo)
      {
        if(_target == 'TextTabFrame')
        {
          m_textFrameScrollMoreOnTopTimeOut = window.setTimeout("TextScrollMoreFromTop('TextTabFrame'," + _scrollTop + "," + _amount + ")", m_textFrameScrollDelay);
        }
      }
  }    
}

function SwitchTextTabControlMode(_editable)
{

  if(_editable != null && _editable == true )
  {
    // text view edit mode
    var div = document.getElementById('TextTabControlContent'); //readmode
    if(div != null)
    {
      div.style.display = 'none';
      // hide link button by default, will show on callback trigger
      KGTextTabControl_HideOrShowTextViewOptionDiv(false);
    }
    var div2 = document.getElementById('TextViewControlContent'); // editmode
    if(div2 != null && div2.style.display != 'block')
    {
      div2.style.display = 'block';
      // hide link button by default, will show on callback trigger
      KGTextTabControl_HideOrShowPreviewFullTVButton(false);
      KGTextTabControl_HideOrShowTextViewEditButton(false);
      
      KGTextTabControl_AdjustTextViewControlSize();
      
    }
    
  }
  else
  {
    var div2 = document.getElementById('TextViewControlContent');
    if(div2 != null)
    {
      div2.style.display = 'none';
      // hide link button by default, will show on callback trigger
      KGTextTabControl_HideOrShowPreviewFullTVButton(false);
    }
    var div = document.getElementById('TextTabControlContent');
    if(div != null && div.style.display != 'block')
    {
      div.style.display = 'block';
      // hide link button by default, will show on callback trigger
      KGTextTabControl_HideOrShowTextViewOptionDiv(false);
      KGTextTabControl_HideOrShowTextViewEditButton(false);
      
      //if(navigator.userAgent.indexOf('Safari') != -1)
      //{
        //row.style.height = (row.parentNode.clientHeight - 10) + 'px';
        //row.style.width = (row.parentNode.clientWidth - 10) + 'px';
      //}
    }
    
    
  }
}

function KGTextTabControl_HideOrShowPreviewFullTVButton(_show)
{
  var btn = document.getElementById('TextViewPreviewSwitch');
  
  if(btn != null)
  {
    if(_show == true)
    {
        btn.style.display = 'block';
    }
    else
    {
        btn.style.display = 'none';
    }
  }
}

function KGTextTabControl_HideOrShowTextViewEditButton(_show, _reset)
{
  var btn = document.getElementById('TextViewEditSwitch');
  
  if(btn != null)
  {
    if(_reset == true)
    {
      m_bWhatTextWritable = false;
      SetInnerText(btn, "Start Editing"); 
    }
      
    if(_show == true)
    {
        btn.style.display = 'block';
    }
    else
    {
        btn.style.display = 'none';
    }
  }
}

function SwitchSingleTextViewEditing()
{
  if(m_bWhatTextWritable != true) 
  {
    // need to go into edit mode
    // check whether the textview is for currently selected what
    // and whether it's a UserKI what
    if(CurrentlyShowingWhats !=  true || m_strFrameSelectedKnowdeID == null || m_strFrameSelectedKnowdeID == '' 
      || GetGlobalHighlightedWhatId() != m_strFrameSelectedKnowdeID || m_IsEditFromNewWhat == true
      || globalLastHighlightedWhat == null || globalLastHighlightedWhat.getAttribute('IsUserKI') != 'true'
      || AllowWhatEditOnly != 1)
    {
      alert("You are not allow to edit this knowde's text.");
      return;
    }
    
    m_bWhatTextWritable = true;
    
    // go into edit mode
    AutoLoadTextViewForKnowde('StartSingleTextEditing', m_strFrameSelectedKnowdeID);

  }
  else
  {
    m_bWhatTextWritable = false;
    
    if(m_bTextViewWritable == true && m_EditFrame != null) 
    {
      SwitchTextViewEditing();
    }    

    AutoLoadTextViewForKnowde('StopEditing', m_strFrameSelectedKnowdeID);
  }
      
   var switchBtn = document.getElementById('TextViewEditSwitch');

   if(switchBtn != null)
   {
     if(m_bWhatTextWritable == true)
      SetInnerText(switchBtn, "Stop Editing"); 
     else
      SetInnerText(switchBtn, "Start Editing"); 
   }
}

var globalAutoFocusTextView = true;
function HandleNewKnowdeForTextView()
{
	globalAutoFocusTextView = false;
	
  SaveCurrentlyEditingTextView(false);
  
  m_EditFrameDiv = document.getElementById('TextViewEditFrameDiv');

  if(m_EditFrameDiv != null)
  {
    m_EditFrameDiv.innerHTML = "";
    SetAutoSaveButtonStatus(-1);
  }
  globalLastTickerAction = "";
}



