function getSEOAssistantRTEPlugIn(prefix) {

   var p = new RTEPlugIn(prefix + "SEOAssistant");
   p.height = 170;
   p.menuHeight = 22;


   var tb = document.getElementById(prefix + 'EditorHost');
//   p.toolbar.style.width = (tb.offsetWidth - 10) + "px";
   p.toolbar.style.height = this.height + "px";
   p.toolbar.style.border = "solid 1px #a5acb2";
   p.toolbar.style.marginTop = "3px";
   p.toolbar.style.marginBottom = "3px";
   p.toolbar.style.padding = "5px";

   p.invalidate = initSEOAssistant;
   p.run = function () {};

   p.data = prefix;
   return p;
}


function initSEOAssistant() {
   var sb = "<input type='hidden' id='" + this.data + "SeoBarCurTab' value='" + this.data + "SeoTipsHost' /><div id='" + this.data + "SeoMenuBar' style='height: " + this.menuHeight + "px;'><div class='rte_tab_sel' id='" + this.data + "SeoMenuItem_SeoTipsHost' onclick=\"setCurrentRTETab('" + this.data + "', 'SeoTipsHost');\">SEO Tips</div><div class='rte_tab' id='" + this.data + "SeoMenuItem_PageDescription' onclick=\"setCurrentRTETab('" + this.data + "', 'PageDescriptionHost');\">Page Description</div><div class='rte_tab' id='" + this.data + "SeoMenuItem_KeyWords' onclick=\"setCurrentRTETab('" + this.data + "', 'KeyWordsHost');\">Keywords</div></div>";
   this.toolbar.style.width = this.editor.width + "px";
   this.toolbar.innerHTML = sb;

   var h = this.height - this.menuHeight - 15;
   sb = "<div id='" + this.data + "SeoTipsHost' style='overflow: auto; margin-top: 5px; height: " + h + "px;'></div>";
   sb += "<div id='" + this.data + "PageDescriptionHost' style='overflow: hidden; margin-top: 5px; height: " + h + "px; display: none;'><textarea id='" + this.data + "PageDescription' style='width: 100%; height: " + (h - 5) + "px; border: none; font-size: 10pt; font-family: sans-serif; background: transparent;' onkeyup=\"document.getElementById('" + this.data + "Descr_' + document.getElementById('" + this.data + "' + 'CurrentLanguage').value + '_' + document.getElementById('" + this.data + "' + 'CurrentPage').value).value = safeString(this.value);\" onmouseup=\"document.getElementById('" + this.data + "Descr_' + document.getElementById('" + this.data + "' + 'CurrentLanguage').value + '_' + document.getElementById('" + this.data + "' + 'CurrentPage').value).value = safeString(this.value);\"></textarea></div>";
   sb += "<div id='" + this.data + "KeyWordsHost' style='display: none; font-size: 8pt; margin-top: 5px;'><div style='height: 15px;'><div style='float: left; width: 59%;font-weight: bold;'>Phrases</div><div style='font-weight: bold;'><span style='float: right;'>[&nbsp;<span class='menuitem' onclick=\"toggleTagEditor('" + this.data + "');\" id='" + this.data + "KeyWordListEditButton'>Edit</span>&nbsp;|&nbsp;<span class='menuitem' onclick=\"clearTagList('" + this.data + "');\">Clear</span>&nbsp;]</span>Keywords</div></div><div style='float: left; width: 59%; font-wight: bold; height: " + (h - 35) + "px; overflow: auto; margin-right: 5px;' id='" + this.data + "KeyWords'>Phrases</div><input type='hidden' id='" + this.data + "KeyWordsList' value='' /><div style='width: 39%; height: " + (h - 35) + "px; overflow: auto; display: block; padding-top: 1px;' id='" + this.data + "KeyWordsListHost'></div><textarea style=\"width: 35%; height: " + (h - 35) + "px; display: none; background: none; margin: 0px; font-size: 8pt; font-family: 'Tahoma', sans-serif; padding-left: 5px; padding-top: 1px;\" id='" + this.data + "KeyWordsListEditor' onkeyup=\"updateTagListFromEditor('" + this.data + "');\"></textarea><div style='height: 20px;'>Settings: <input type='checkbox' onclick=\"autoGatherTags('" + this.data + "');refreshTagList('" + this.data + "');\" id='" + this.data + "KeyWordsSettingsOnTheFly' /><label for='" + this.data + "KeyWordsSettingsOnTheFly'>On-the-fly</label> <input type='checkbox' id='" + this.data + "KeyWordsHideIrrelevant' onclick=\"gatherTags('" + this.data + "');refreshTagList('" + this.data + "');\" checked='checked' /><label for='" + this.data + "KeyWordsHideIrrelevant'>Hide irrelevant tags</label> [<span class='menuitem' onclick=\"gatherTags('" + this.data + "');refreshTagList('" + this.data + "');\">Refresh</span>]</div></div>";
   this.toolbar.innerHTML += sb;
}




function tagOccurenceSorter(a, b) {
   return b[1] - a[1];
}


function checkTag(tag, tags) {
   var j = 0;
   while (j < tags.length && tag != tags[j][0]) j++;
   if (j < tags.length) {
      tags[j][1]++;
   } else {
      tags.push([tag, 1, 0, 0]);
   }
}

function markTags(total_length, tags) {
   var i;
   for (i = 0; i < tags.length; i++) {
      var p = Math.round(tags[i][1] / total_length * 10000) / 100;
      tags[i][2] = p;
      if (p < 1) tags[i][3] = 0;
         else if (p < 2) tags[i][3] = 1;
         else if (p < 8) tags[i][3] = 2;
         else tags[i][3] = 3;
   }
}



function updateTagList(name, taglist, no_update_editor) {

   if (taglist == null) {
      document.getElementById(name + 'KeyWordsListEditor').value = "";
      document.getElementById(name + 'KeyWordsListHost').innerHTML = "";
      return;
   }

   if (!no_update_editor) document.getElementById(name + 'KeyWordsListEditor').value = taglist.join("\r\n");

   var i;
   for (i = 0; i < taglist.length; i++) {
      taglist[i] = "<div class='seoa_item'>" + taglist[i] + "<span style='float: right;'><img src='webcpms/icons/check_x.gif' height='8' title='Remove from list' onclick=\"removeTagFromList('" + name + "', '" + taglist[i] + "');\" /></span></div>";
   }

   var host = document.getElementById(name + 'KeyWordsListHost');
   host.innerHTML = taglist.join("\r\n");
}


function refreshTagList(name) {
   if (document.getElementById('PageHomeKeyWordsListHost')) {
      var lang = document.getElementById(name + "CurrentLanguage").value;
      var page = document.getElementById(name + "CurrentPage").value;
      var taglist = null;
      if (document.getElementById(name + 'Tags_' + lang + '_' + page).value != "") {
         taglist = document.getElementById(name + 'Tags_' + lang + '_' + page).value.split(",");
      }
      updateTagList(name, taglist);
   }
}


function addTagToList(name, tag) {
   var lang = document.getElementById(name + "CurrentLanguage").value;
   var page = document.getElementById(name + "CurrentPage").value;
   var taglist;
   if (document.getElementById(name + 'Tags_' + lang + '_' + page).value == "") {
      document.getElementById(name + 'Tags_' + lang + '_' + page).value = tag;
      taglist = [tag];
   } else {
      taglist = document.getElementById(name + 'Tags_' + lang + '_' + page).value.split(",");

      var i = 0;
      while (i < taglist.length && taglist[i] != tag) i++;
      if (i >= taglist.length) {
         taglist.push(tag);
      }
      document.getElementById(name + 'Tags_' + lang + '_' + page).value = taglist.join(",");
   }

   updateTagList(name, taglist);
}


function removeTagFromList(name, tag) {
   var lang = document.getElementById(name + "CurrentLanguage").value;
   var page = document.getElementById(name + "CurrentPage").value;

   var taglist = document.getElementById(name + 'Tags_' + lang + '_' + page).value.split(",");
   var i = 0;
   while (i < taglist.length && taglist[i] != tag) i++;
   if (i < taglist.length) {
      taglist.splice(i, 1);
   }
   document.getElementById(name + 'Tags_' + lang + '_' + page).value = taglist.join(",");

   updateTagList(name, taglist);
}

function clearTagList(name) {
   if (!confirm("Really remove all tags?")) {
      return;
   }
   var lang = document.getElementById(name + "CurrentLanguage").value;
   var page = document.getElementById(name + "CurrentPage").value;
   document.getElementById(name + 'Tags_' + lang + '_' + page).value = "";
   updateTagList(name);
}

function toggleTagEditor(name) {
   var d = document.getElementById(name + "KeyWordsListHost").style.display == "block" ? true : false;

   toggle(name + "KeyWordsListHost", !d);
   toggle(name + "KeyWordsListEditor", d);

   document.getElementById(name + 'KeyWordListEditButton').innerHTML = d ? "Finish" : "Edit";

   refreshTagList(name);

   if (!d) {
      document.getElementById(name + 'KeyWordsListEditor').focus();
   }
}

function updateTagListFromEditor(name) {
   var taglist = document.getElementById(name + 'KeyWordsListEditor').value.split("\n");
   var lang = document.getElementById(name + "CurrentLanguage").value;
   var page = document.getElementById(name + "CurrentPage").value;
   document.getElementById(name + 'Tags_' + lang + '_' + page).value = taglist.join(",");
   updateTagList(name, taglist, true);
}



function gatherTags(name, page, lang, text) {
   if (lang == null) lang = document.getElementById(name + "CurrentLanguage").value;
   if (page == null) page = document.getElementById(name + "CurrentPage").value;
   if (text == null) text = document.getElementById(name + "InnerStorage_" + lang + "_" + page).value.toLowerCase();

   var text = stripHTML(text, true);
   var taglist = text.split(" ");
   var tags1 = [], tags2 = [], tags3 = [];

   var i, j;

   for (i = 0; i < taglist.length; i++) {
      if (taglist[i].length < 3 || (i < taglist.length - 1 && taglist[i + 1].length < 3) || (i < taglist.length - 2 && taglist[i + 2].length < 3)) {
         continue;
      }
      checkTag(taglist[i], tags1);
      if (i < taglist.length - 1) checkTag(taglist[i] + " " + taglist[i + 1], tags2);
      if (i < taglist.length - 2) checkTag(taglist[i] + " " + taglist[i + 1] + " " + taglist[i + 2], tags3);
   }

   tags1.sort(tagOccurenceSorter);
   tags2.sort(tagOccurenceSorter);
   tags3.sort(tagOccurenceSorter);

   markTags(taglist.length, tags1);
   markTags(taglist.length / 2, tags2);
   markTags(taglist.length / 3, tags3);

   var tags = [tags3, tags2, tags1];

   var taghost = document.getElementById(name + "KeyWords");
   if (taghost != null) {
      var t = [];
      for (i = 0; i < tags.length; i++) {
         var n;
         switch (i) {
            case 0:
               n = "Three-word phrases";
               break;
            case 1:
               n = "Two-word phrases";
               break;
            case 2:
               n = "Single words";
               break;
         }
         t.push("<div style='font-weight: bold; margin: 5px;'>" + n + "</div><div style='margin: 5px;'>");
         for (j = 0; j < tags[i].length; j++) {
            var c, e;
            switch (tags[i][j][3]) {
               case 0:
                  c = "#c0c0c0";
                  e = "irrelevant";
                  break;
               case 1:
                  c = "black";
                  e = "candidate";
                  break;
               case 2:
                  c = "#146c21";
                  e = "good";
                  break;
               case 3:
                  c = "#ba3f4b";
                  e = "keyword stuffing";
                  break;
            }
            var show = true;
            if (document.getElementById(name + 'KeyWordsHideIrrelevant') && document.getElementById(name + 'KeyWordsHideIrrelevant').checked && tags[i][j][3] == 0) show = false;
            if (show) t.push("<span class='seoa_item' title='Add to list' onclick=\"addTagToList('" + name + "', '" + tags[i][j][0] + "');\">" + tags[i][j][0] + " (<span style='color: " + c + ";'>" + tags[i][j][2] + "% - " + e + "</span>)</span><br />");
         }
         t.push("</div>");
      }
      taghost.innerHTML = t.join("\r\n");
   }
}


function autoGatherTags(name) {
   var host = document.getElementById(name + 'SeoTipsHost');
   if (host == null) return;

   if (document.getElementById(name + 'KeyWordsSettingsOnTheFly').checked) {
      gatherTags(name);
   }
}






function analyzeDocument(name) {
   var host = document.getElementById(name + 'SeoTipsHost');
   if (host == null) return;

   var issues = new Array();

   var lang = document.getElementById(name + "CurrentLanguage").value;
   var page = document.getElementById(name + "CurrentPage").value;
   var text = document.getElementById(name + "InnerStorage_" + lang + "_" + page).value;
   var tags = document.getElementById(name + "Tags_" + lang + "_" + page).value;
   var editor = document.getElementById(name + "EditorFrame").contentWindow.document;

   // check title tags and page descriptions
   var notitle = new Array();
   var i = 1;
   var t;
   while ( (t = document.getElementById(name + "Title_" + lang + "_" + i)) != null ) {
      if (t.value.length == 0) notitle[notitle.length] = i;
      i++;
   }
   if (notitle.length > 0) {
      issues[issues.length] = "<span class='issue_w2'>You should provide page title for page(s) " + join(notitle, ", ", " and ") + ".</span>";
   }
   var nodescr = new Array();
   var i = 1;
   var d;
   while ( (d = document.getElementById(name + "Descr_" + lang + "_" + i)) != null ) {
      if (d.value.length == 0) nodescr[nodescr.length] = i;
      i++;
   }
   if (nodescr.length > 0) {
      issues[issues.length] = "<span class='issue_w1'>You should provide page description for page(s) " + join(nodescr, ", ", " and ") + ".</span>";
   } else {

      // too short meta description
      var descr = unSafeString(document.getElementById(name + "Descr_" + lang + "_" + page).value);
      var d = descr.split(" ");
      if (d.length < 8 || descr.length < 50) {
         issues[issues.length] = "<span class='issue_w1'>Page description is too short. Write one or two complete sentences with at least 8-10 words and/or at least 50 characters.</span>";
      }
      if (descr.length >= 150) {
         issues[issues.length] = "<span class='issue_w1'>Page description is too long. It should not exceed 150 characters.</span>";
      }
   }

   // check multiple h1 tags
   var ltext = text.toLowerCase();
   var idx1 = ltext.indexOf("<h1>");
   var idx2 = ltext.lastIndexOf("<h1>");
   if (idx1 == -1 || (idx1 > -1 && idx2 > -1 && idx1 != idx2)) {
//      issues[issues.length] = "<span class='issue_w2'>You should have exactly one <b>Heading 1</b> text in your document.</span> <span class='menuitem' onclick=\"scrollToIssue('" + name + "')\">View &gt;&gt;</span>";
      issues[issues.length] = "<span class='issue_w2'>You should have exactly one <b>Heading 1</b> text in your document.</span>";
   }

   // check if page title and h1 are the same
   t = document.getElementById(name + "Title_" + lang + "_" + page).value;
   if (t.length > 0) {
      idx2 = ltext.indexOf("</h1>", idx1);
      var h1 = ltext.substring(idx1 + 4, idx2);
      if (decodeURIComponent(t).toLowerCase() != h1) {
         issues[issues.length] = "<span class='issue_w1'>Page title and <b>Heading 1</b> text should be the same.</span>";
      }
   }

   // check anchor captions: 'click here' and the like...
   if (editor.links) {
      var ch = new Array();
      for (i = 0; i < editor.links.length; i++) {
         if (editor.links[i].innerHTML.toLowerCase().indexOf("click") > -1) {
            ch[ch.length] = editor.links[i].offsetTop;
         }
      }
      if (ch.length > 0) {
         var v = new Array();
         for (i = 0; i < ch.length; i++) {
            v[v.length] = "<span class='menuitem_small' onclick=\"scrollToIssue('" + name + "', " + ch[i] + ")\">Issue&nbsp;#" + (i + 1) +"</span> ";
         }
         issues[issues.length] = "<span class='issue_w2'>Avoid the term <i>'Click here'</i> in link captions. You should specify a more descriptive text. </span>" + v.join(", ");
      }
   }

   // check if anchor caption is too long
   if (editor.links) {
      var ch = new Array();
      for (i = 0; i < editor.links.length; i++) {
         var sh = stripHTML(editor.links[i].innerHTML);
         var c = sh.split(" ");
         var len = sh.length;
         if (c.length > 7 || len > 50) {
            ch[ch.length] = editor.links[i].offsetTop;
         }
      }
      if (ch.length > 0) {
         var v = new Array();
         for (i = 0; i < ch.length; i++) {
            v[v.length] = "<span class='menuitem_small' onclick=\"scrollToIssue('" + name + "', " + ch[i] + ")\">Issue&nbsp;#" + (i + 1) +"</span> ";
         }
         issues[issues.length] = "<span class='issue_w1'>Too long link captions. You should specify shorter text while keeping it relevant. </span>" + v.join(", ");
      }
   }

   // check if img alt attribute exists
   if (editor.images) {
      var ch = new Array();
      for (i = 0; i < editor.images.length; i++) {
         var noalt = false;
         if (editor.images[i].alt == null) {
            noalt = true;
         } else if (editor.images[i].alt.length == 0) {
            noalt = true;
         }
         if (noalt) {
            ch[ch.length] = editor.images[i].offsetTop;
         }
      }
      if (ch.length > 0) {
         var v = new Array();
         for (i = 0; i < ch.length; i++) {
            v[v.length] = "<span class='menuitem_small' onclick=\"scrollToIssue('" + name + "', " + ch[i] + ")\">Issue&nbsp;#" + (i + 1) +"</span> ";
         }
         issues[issues.length] = "<span class='issue_w2'>You should specify alternative text for images. </span>" + v.join(", ");
      }
   }

   // check if text is too short
   var num_words = stripHTML(text).split(" ").length;
   if (num_words < 300) {
      issues[issues.length] = "<span class='issue_w1'>Text is too short. Write at least 300 words of relevant content.</span>";
   }

   // check tags
   var t = tags.split(",");
   if (t.length == 0) {
      issues[issues.length] = "<span class='issue_w2'>No keywords specified. Select the keywords that describe this page.</span>";
   } else if (t.length > 10) {
      issues[issues.length] = "<span class='issue_w1'>Too many phrases. You should select no more than 10 keywords.</span>";
   }

   if (issues.length > 0) {
      document.getElementById(name + 'SeoTipsHost').innerHTML = issues.join("<br />");
   } else {
      document.getElementById(name + 'SeoTipsHost').innerHTML = "";
   }
}


function scrollToIssue(name, pos) {
   document.getElementById(name + "EditorFrame").contentWindow.scrollTo(0, pos);
}
