// ==UserScript==
// @name           AllegroTools (komentarze) dla IE i FF
// @namespace      http://www.allegrotoolsie.hopto.org/
// @description    Dodatkowe narzedzia pomocne przy przegladaniu komentarzy uzytkownikow Allegro // v0.20090127.0
// @include        http*://*allegro.pl/show_user.php?*
// @include        http*://*allegro.pl/my_allegro.php?*page=feedbacks
// @include        http*://*allegro.pl/my_allegro.php?*page=feedbacks*type=fb_recvd*
// @include        http*://*allegro.pl/my_allegro.php?*page=feedbacks*type=fb_gave*
// @include        http*://*allegro.pl/my_allegro.php?*page=feedbacks*type=fb_add*
// @exclude        http*://*allegro.pl/*no_limit=1*
// ==/UserScript==

(function(){

var SELLER_COLORS = new Array("#FFD9C6", "#FFE8DD");
var BUYER_COLORS = new Array("#C6D9FF", "#DDE8FF");

var SELLER_STRING = "Sprzedaj";
var BUYER_STRING = "Kupuj";
var POSITIVE_STRING = "Pozytywny";
var NEUTRAL_STRING = "Neutralny";
var NEGATIVE_STRING = "Negatywny";

var ALL_BTN = "_all_btn_";
var SELLERS_BTN = "_sellers_btn_";
var BUYERS_BTN = "_buyers_btn_";
var CHECK_LINKS_BTN = "_check_links_btn_";
var COLORING_CHBX = "_coloring_chkbx_";
var THUMBNAILS_CHBX = "_thumbnails_chkbx_";
var AUTOCHECK_CHBX = "_autocheck_chkbx_";
var ARCH_CHBX = "_arch_chkbx_";
var SHOW_EMPTY_ARCH_CHBX = "_show_empty_arch_chkbx_";
var COMMENTS_ALL_BTN = "_comments_all_btn_";
var COMMENTS_POSITIVE_BTN = "_comments_positive_btn_";
var COMMENTS_NEUTRAL_BTN = "_comments_neutral_btn_";
var COMMENTS_NEGATIVE_BTN = "_comments_negative_btn_";

var AT_COMMENT_TYPE_FILTER = "AT_C_comment_type_filter";
var AT_FILTER = "AT_C_filter";
var AT_COLORING = "AT_C_coloring";
var AT_THUMBNAILS = "AT_C_thumbnails";
var AT_AUTOCHECK = "AT_C_autocheck";
var AT_ARCH_PREFIX = "AT_C_arch_";
var AT_SHOW_EMPTY_ARCH = "AT_C_show_empty_arch";

var COMMENT_TABLE = false;
var COMMENTS = new Array();

var BG_BYSTR = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAQAAAAECAIAAAFRlDm/AAAAB3RJTUUH1gwHDRgVt4pvywAAAAlwSFlzAAAPYQAAD2EBqD+naQAAAARnQU1BAACxjwv8YQUAAAAYSURBVHjaY/j/nwEGoEwQBWEyoovDFQMAkc0N9HFYUnUAAAAASUVORK5CYII=";

var showCommentTypeFilter = false;
var showCommentSourceFilter = false;
var isAddFeedbackPage = false;
var isRecvdFeedbackPage = false;
var showEmptyArch = true;

//////////////////////////////////////////////
// Generic definitions for archivers
//////////////////////////////////////////////

var ARCH_AUCTION_NOT_FOUND = "Aukcja nie wystepuje w archiwum";
var ARCH_AUCTION_CHECK_IN_PROGRESS = "Pobierane tytulu aukcji, prosze czekac...";
var ARCH_AUCTION_CHECK_ERROR = "Nie udalo sie sprawdzic tytulu aukcji";

function processGenericError(linkChecker, archiver)
{
  var titleTD = document.getElementById(archiver.name + "_title_" + linkChecker.index);
  titleTD.innerHTML = ARCH_AUCTION_CHECK_ERROR;
  linkChecker.unmark(linkChecker.linkTD);
}

function processGenericMultiError(linkChecker, archiver)
{
  for(var i= 0; i < linkChecker.length; i++)
  {
    var titleTD = document.getElementById(archiver.name + "_title_" + linkChecker[i].index);
    titleTD.innerHTML = ARCH_AUCTION_CHECK_ERROR;
    linkChecker[i].unmark(linkChecker[i].linkTD);
  }  
}

function processGenericMultiResponse(d, linkChecker, archiver)
{
  for(var i= 0; i < linkChecker.length; i++)
  {
    var titleTD = document.getElementById(archiver.name + "_title_" + linkChecker[i].index);
    var re = new RegExp(linkChecker[i].auctionNumber + ":(.+)", "i");
    if(d.responseText.match(re))
    {
      var title = RegExp.$1;
      titleTD.innerHTML = "<a target='_blank' href='" + archiver.archiveUrl.replace(/%number%/, linkChecker[i].auctionNumber) + "'>" + title + "</a>";
    }
    else
    {
      if(showEmptyArch == true)
      {
        titleTD.innerHTML = ARCH_AUCTION_NOT_FOUND;
      }
      else
      {
        var titleTR = titleTD.parentNode;
        titleTR.parentNode.removeChild(titleTR);
      }
    }
    linkChecker[i].unmark(linkChecker[i].linkTD);
  }  
}

//////////////////////////////////////////////
// Definition of ALLEGRO archiver
//////////////////////////////////////////////

function processAllegroResponse(d, linkChecker, archiver)
{
  var titleTD = document.getElementById(archiver.name + "_title_" + linkChecker.index);
  if (d.responseText.match(/<span class="small">\((.{3} \d{2} .{3} \d{4} \d{2}:\d{2}:\d{2} .+?)\)<\/span>/))
  {
    linkChecker.linkTD.innerHTML = RegExp.$1 + "<br>" + linkChecker.linkTD.innerHTML;
    var title = getTitle(d.responseText);
    var price = getPrice(d.responseText);
    titleTD.innerHTML = "<a target='_blank' href='" + archiver.archiveUrl.replace(/%number%/, linkChecker.auctionNumber) + "'>" + title + "</a>" + " - " + price;

    var thumbnailTD = document.getElementById("_thumbnail_" + linkChecker.index);
    if(thumbnailTD)
    {
      var thumbnailURL = getThumbnailURL(d.responseText);
      if(thumbnailURL)
      {
        thumbnailTD.innerHTML = "<img src='" + thumbnailURL + "' border='0' width='64' height='48'></img>";
      }
    }  

    linkChecker.unmark(linkChecker.linkTD);
  }
  else
  {
    ARCH_OLD_ALLEGRO.check(linkChecker);
  }
}

function processAllegroError(linkChecker, archiver)
{
  linkChecker.linkTD.innerHTML = getInnerText(linkChecker.linkTD);
  processGenericError(linkChecker, archiver);
}

var ARCH_ALLEGRO = new Archiver("Allegro", false,
                                 "http://allegro.pl/show_item.php?item=%number%",
                                 "http://allegro.pl/show_item.php?item=%number%",
                                 processAllegroResponse, processAllegroError);

//////////////////////////////////////////////
// Definition of OLD ALLEGRO archiver
//////////////////////////////////////////////

function processAllegroOldResponse(d, linkChecker, archiver)
{
  var titleTD = document.getElementById(archiver.name + "_title_" + linkChecker.index);
  if(d.responseText.match(/<td class="formtitle" colspan="2">Dane kontaktowe Kontrahenta<\/td>/))
  {
    if (d.responseText.match(/<td class="form2"><a href=\"\/item\d+?.*?.html\">(.*?)<\/a>/))
    {
      titleTD.innerHTML = RegExp.$1;
    }
    else
    {
      if(showEmptyArch == true)
      {
        titleTD.innerHTML = ARCH_AUCTION_NOT_FOUND;
      }
      else
      {
        var titleTR = titleTD.parentNode;
        titleTR.parentNode.removeChild(titleTR);
      }
    }
  }
  else
  {
    titleTD.innerHTML = "Aby sprobowac odnalezc i wyswietlic tytul aukcji <a href='http://allegro.pl/my_allegro.php?mm=1' target='_blank'>zaloguj sie na Allegro</a> a nastepnie odswiez te strone";
  }
  linkChecker.unmark(linkChecker.linkTD);
}

var ARCH_OLD_ALLEGRO = new Archiver("Allegro", false,
                                     "http://allegro.pl/my_allegro.php?page=feedbacks&type=us_data&item_id=%number%",
                                     null,
                                     processAllegroOldResponse, processGenericError);

//////////////////////////////////////////////
// Definition of PAA archiver
//////////////////////////////////////////////

var ARCH_PAA = new Archiver("PAA", true,
                             "http://paa.pl/_idsearch.php?id=%number%",
                             "http://paa.pl/szukaj/?itemid=%number%",
                             processGenericMultiResponse, processGenericMultiError);

//////////////////////////////////////////////
// Definition of ARCHIWIZATOR archiver
//////////////////////////////////////////////

var ARCH_ARCHIWIZATOR = new Archiver("Archi-wizator", true,
                                      "http://archi.inosak.org/db/titles.html?id=%number%",
                                      "http://archi.inosak.org/db/item%number%_1.html",
                                      processGenericMultiResponse, processGenericMultiError);

//////////////////////////////////////////////
// Definition of ALLEGROMAT archiver
//////////////////////////////////////////////

function processAllegromatResponse(d, linkChecker, archiver)
{
  for(var i= 0; i < linkChecker.length; i++)
  {
    var titleTD = document.getElementById(archiver.name + "_title_" + linkChecker[i].index);
    var re = new RegExp(linkChecker[i].auctionNumber + ":(.*?)<br>", "i");
    d.responseText.match(re);
    var title = RegExp.$1;
    if(title)
    {
      titleTD.innerHTML = "<a target='_blank' href='" + archiver.archiveUrl.replace(/%number%/, linkChecker[i].auctionNumber) + "'>" + title + "</a>";
    }
    else
    {
      if(showEmptyArch == true)
      {
        titleTD.innerHTML = ARCH_AUCTION_NOT_FOUND;
      }
      else
      {
        var titleTR = titleTD.parentNode;
        titleTR.parentNode.removeChild(titleTR);
      }
    }
    linkChecker[i].unmark(linkChecker[i].linkTD);
  }  
}

var ARCH_ALLEGROMAT = new Archiver("Allegromat", true,
                                    "http://allegromat.pl/index.php?a=szukaj_at&str=%number%",
                                    "http://allegromat.pl/index.php?a=szukaj&str=%number%",
                                    processAllegromatResponse, processGenericMultiError);

/////////////////////////////////////////////////////////////////
var ARCHIVERS = new Array(ARCH_ALLEGRO, ARCH_PAA, ARCH_ARCHIWIZATOR, ARCH_ALLEGROMAT);


/////////////////////////////////////////////////////////////////
// Data parsing functions
/////////////////////////////////////////////////////////////////

function getTitle(str)
{
  if(str.match(/<div.*?>\s*?(.+?) <span class="nobold">\(numer \d+?\)<\/span>\s*?<\/div>/))
  {
    return RegExp.$1;
  }
  else
  {
    return null;
  }
}

function getPrice(str)
{
  if(str.match(/<tr>\s*?<td.*?>(Cena <span class="textBN">Kup Teraz<\/span>:|Aktualna cena)<\/td>\s*?<td.*?><b>(.*?)<\/b>.*?\s*?<\/td>\s*?<\/tr>/))
  {
    return RegExp.$2;
  }
  else
  {
    return null;
  }
}

function getPaaPrice(str)
{
  if(str.match(/<strong style="font-size:big; color:red">Cena: (.*?)<\/strong>/i))
  {
    return RegExp.$1;
  }
  else
  {
    return null;
  }
}

function checkError(str)
{
  if(str.match(/<table.*?class="table-error".*?>/g))
  {
    return true;
  }
  else
  {
    return false;
  }
}

/*
 * Retrieves URL to thumbnail from the auction (if any)
 */
function getThumbnailURL(str)
{
// <a href="#gallery"><img src=http://photos04.allegro.pl/photos/128x96/449/39/00/449390027 width="80" height="60" style="border: 1px solid #ffcc00" alt="Oryg. uchwyt Nokia HH-12 + CR-39 DWUPAK od MSA FV" title="Oryg. uchwyt Nokia HH-12 + CR-39 DWUPAK od MSA FV" />
  if(str.match(/<a href="#gallery"><img src=(.*?) .*?<\/a>/))
  {
    return RegExp.$1;
  }
  else
  {
    return null;
  }
}

/////////////////////////////////////////////////////////////////
//// IE/FF compatibility
/////////////////////////////////////////////////////////////////

function select()
{
  if (arguments.length>1) {
    var node = arguments[0];
    for (var i=1; i<arguments.length; i++) {
      if (typeof(arguments[i])=='string') {
        node = node.getElementById(arguments[i]);
      } else {
        var nodeIdx = arguments[i];
        var children = getChildNodes(node);
        if (nodeIdx<children.length) {
          node = children[nodeIdx];
        } else {
          node = null;
          break;
        }
      }
    }
  }
  return node;
}

// FF uses addEventListener method while IE uses attachEvent method
// to register event handler
// Call this mehod with the element that generates the event,
// the event name (without 'on' prefix) and the handler routine
// The handler routine should accept an event source
// See getEvent method to see how to get the event source in FF and IE
function registerEventHandler(element, eventName, handler)
{
  if (element.addEventListener)
  {
    element.addEventListener(eventName, handler, false);
  }
  else if (document.attachEvent)
  {
    element.attachEvent("on" + eventName, handler);
  }
} 

// FF passes event to the handler function, while IE does not
// Call this function fit the ergument of the handler function:
// If e is not null (FF) then it will be returned. Otherwise (IE)
// the event will be retrieved from the window object and this value
// will be returned instead.
function getEvent(source)
{
  if (source)
  {
    return source;
  }
  else
  {
    return window.event;
  }
}

// In FF childNodes returns also #text nodes that represents
// the whitespaces in the HTML source. IE skips these nodes
// For IE and FF use this method instead of childNodes property
// to return all children of an element.
// NOTE: this method skips ALL #text nodes (not only whitespaces)
function getChildNodes(element)
{
  var children = new Array();
 
  if(element)
  {
    var child = element.firstChild;
    while(child)
    {
      if (child.nodeType == 1)
      {
        children.push(child);
      }
      child = child.nextSibling;
    }
  }
  
  return children;
}

// FF uses textContent property while IE uses innerText property
// to return the inner text of an element
function getInnerText(element)
{
  var result = null;
  
  if (element)
  {
    // For IE
    result = element.innerText;
  
    if(result == null)
    {
      // For FireFox
      result = element.textContent;
    }
  }
  
  return result;
}

// In FF firstChild returns also #text nodes that represents
// the whitespaces in the HTML source. IE skips these nodes
// For IE and FF use this method instead of firstChild property
// to return the first non-#text element.
// NOTE: this method skips ALL #text nodes (not only whitespaces)
function getFirstChild(element)
{
  var child = element.firstChild;
  while(child && (child.nodeType != 1))
  {
    child = child.nextSibling;
  }
  
  return child;
}

// Returns the number-th next sibling of the element
// for IE/FF compatibility skips #text nodes
function getNextSibling(element, number)
{
  var sibling = element;
  while((number > 0) && (sibling))
  {
    sibling = sibling.nextSibling;
    if (sibling && (sibling.nodeType == 1))
    {
      number--;
    }
  }
  
  return sibling;
}

/////////////////////////////////////////////////////////////////
// Event handlers section
/////////////////////////////////////////////////////////////////
function handleCommentsAllButton()
{
  enableButton(COMMENTS_ALL_BTN, false);
  GM_setValue(AT_COMMENT_TYPE_FILTER, COMMENTS_ALL_BTN);
  filterComments();
  enableButton(COMMENTS_POSITIVE_BTN, true);
  enableButton(COMMENTS_NEUTRAL_BTN, true);
  enableButton(COMMENTS_NEGATIVE_BTN, true);
}

function handleCommentsPositiveButton()
{
  enableButton(COMMENTS_POSITIVE_BTN, false);
  GM_setValue(AT_COMMENT_TYPE_FILTER, COMMENTS_POSITIVE_BTN);
  filterComments();
  enableButton(COMMENTS_ALL_BTN, true);
  enableButton(COMMENTS_NEUTRAL_BTN, true);
  enableButton(COMMENTS_NEGATIVE_BTN, true);
}

function handleCommentsNeutralButton()
{
  enableButton(COMMENTS_NEUTRAL_BTN, false);
  GM_setValue(AT_COMMENT_TYPE_FILTER, COMMENTS_NEUTRAL_BTN);
  filterComments();
  enableButton(COMMENTS_ALL_BTN, true);
  enableButton(COMMENTS_POSITIVE_BTN, true);
  enableButton(COMMENTS_NEGATIVE_BTN, true);
}

function handleCommentsNegativeButton()
{
  enableButton(COMMENTS_NEGATIVE_BTN, false);
  GM_setValue(AT_COMMENT_TYPE_FILTER, COMMENTS_NEGATIVE_BTN);
  filterComments();
  enableButton(COMMENTS_ALL_BTN, true);
  enableButton(COMMENTS_POSITIVE_BTN, true);
  enableButton(COMMENTS_NEUTRAL_BTN, true);
}

function handleAllButton()
{
  enableButton(ALL_BTN, false);
  GM_setValue(AT_FILTER, ALL_BTN);
  filterComments();
  enableButton(SELLERS_BTN, true);
  enableButton(BUYERS_BTN, true);
}

function handleSellersButton()
{
  enableButton(SELLERS_BTN, false);
  GM_setValue(AT_FILTER, SELLERS_BTN);
  filterComments();
  enableButton(ALL_BTN, true);
  enableButton(BUYERS_BTN, true);
}

function handleBuyersButton()
{
  enableButton(BUYERS_BTN, false);
  GM_setValue(AT_FILTER, BUYERS_BTN);
  filterComments();
  enableButton(ALL_BTN, true);
  enableButton(SELLERS_BTN, true);
}

function handleCheckLinksButton()
{
  enableButton(CHECK_LINKS_BTN, false);
  checkLinks();
}

function handleColoringCheckbox()
{
  GM_setValue(AT_COLORING, getCheckbox(COLORING_CHBX));
  filterComments();
}

function handleThumbnailsCheckbox()
{
  var thumbnails = getCheckbox(THUMBNAILS_CHBX);
  GM_setValue(AT_THUMBNAILS, thumbnails);
  displayThumbnails(thumbnails);
}

function handleAutocheckCheckbox()
{
  var autocheck = getCheckbox(AUTOCHECK_CHBX);
  GM_setValue(AT_AUTOCHECK, autocheck);
  showButton(CHECK_LINKS_BTN, !autocheck);
  autocheckLinks();
}

function handleShowEmptyArchCheckbox()
{
  GM_setValue(AT_SHOW_EMPTY_ARCH, getCheckbox(SHOW_EMPTY_ARCH_CHBX));
}

function  handleArchCheckbox(e)
{
  var event = getEvent(e);
  var source = event.target || event.srcElement;
  var name = source.id.replace(ARCH_CHBX, "");
  GM_setValue(AT_ARCH_PREFIX + name, getCheckbox(name + ARCH_CHBX));
}


/////////////////////////////////////////////////////////////////
// Links checking related functions
/////////////////////////////////////////////////////////////////

function autocheckLinks()
{
  if(isEnabledButton(CHECK_LINKS_BTN) && getCheckbox(AUTOCHECK_CHBX))
  {
    handleCheckLinksButton();
  }
}

function checkLinks()
{
  if (COMMENTS)
  {
    var linkCheckers = new Array();
    linkCheckers.auctionNumber = "";
    for(var i = 0; i < COMMENTS.length; i++)
    {
      linkCheckers.push(new LinkChecker(i));
      linkCheckers.auctionNumber = linkCheckers.auctionNumber + ((i == 0) ? "" : ",") + linkCheckers[i].auctionNumber;
    }
    for(var i = 0; i < ARCHIVERS.length; i++)
    {
      if((ARCHIVERS[i].multi) && (ARCHIVERS[i].enabled == true))
      {
        ARCHIVERS[i].check(linkCheckers);
      }
    }  
  }
}

////////////////////////////////////////////////////////////////////////
// Archiver class
////////////////////////////////////////////////////////////////////////

function Archiver(name, multi, checkUrl, archiveUrl, processMethod, errorMethod)
{
  // Name of the archiver to be displayed
  this.name = name;
  // Can this archiver handle queris with multiple auctions?
  this.multi = multi;
  // Url of the archiver used to check auction existence
  this.checkUrl = checkUrl;
  // Url of the archiver pointing to the archived auction
  this.archiveUrl = archiveUrl;
  // Method used to analyse archiver response
  this.processMethod = processMethod;
  // Method used to analyse archiver error
  this.errorMethod = errorMethod;
  // Property used to mark whether this archiver is enabled or not
  // Initialized during creation, so changes won;t affect processing
  this.enabled = GM_getValue(AT_ARCH_PREFIX + this.name, true);
}

Archiver.prototype.check = function(linkChecker)
{
  var archiverUrl = this.checkUrl.replace(/%number%/, linkChecker.auctionNumber);
  var me = this;
  GM_xmlhttpRequest({method:"GET", url:archiverUrl,
                     onload:function(d){me.processMethod(d, linkChecker, me);},
                     onerror:function(d){me.errorMethod(linkChecker, me);}});
}

////////////////////////////////////////////////////////////////////////
// LinkChecker class
////////////////////////////////////////////////////////////////////////

function LinkChecker(index)
{
  this.index = index;
  this.row = COMMENTS[this.index];
  if(this.row)
  {
    // Don't check auction link on add feedback page
    if (isAddFeedbackPage == false)
    {
      var link = null;
      if(isRecvdFeedbackPage)
      {
        link = select(this.row, 5, 0);
      }
      else
      { 
        link = select(this.row, 4, 0);
      }  
      if(link)
      {
        this.link = link;
        this.linkTD = link.parentNode;
        if(isRecvdFeedbackPage)
        {
          this.titleTD = select(this.row, 2);
        }
        else  
        {
          this.titleTD = select(this.row, 1);
        }  
        this.auctionNumber = getInnerText(this.link);
        this.checkLink();
      }
    }
  }
}

LinkChecker.prototype.mark = function(element)
{
  if (element)
  {
    if(element.markCount)
    {
      element.markCount += 1;
    }
    else
    {
      element.markCount = 1;
      element.style.backgroundImage = "url('"+BG_BYSTR+"')";
    }
  }
}

LinkChecker.prototype.unmark = function(element)
{
  if (element)
  {
    if(element.markCount && element.markCount > 1)
    {
      element.markCount -= 1;
    }
    else
    {
      element.markCount = 0;
      element.style.backgroundImage = "";
    }
  }
}

LinkChecker.prototype.checkLink = function()
{
  var titleTable = document.createElement('table');
  titleTable.style.color="#606060";
  titleTable.cellPadding = "0";
  titleTable.cellSpacing = "0";
  titleTable.border = "0";
  var titleTableBody = document.createElement('tbody');
  getFirstChild(this.titleTD).style.cssFloat = "none";
  getFirstChild(this.titleTD).style.styleFloat = "none";
  this.titleTD.style.textAlign='left';
  for(var i = 0; i < ARCHIVERS.length; i++)
  {
    if(ARCHIVERS[i].enabled == true)
    {
      var titleTableRow = document.createElement('tr');
      var titleTableCell1 = document.createElement('td');
      titleTableCell1.style.fontSize = '8pt';
      titleTableCell1.innerHTML = "<b>" + ARCHIVERS[i].name + "</b>";
      titleTableRow.appendChild(titleTableCell1);
      var titleTableCell2 = document.createElement('td');
      titleTableCell2.style.fontSize = '8pt';
      titleTableCell2.innerHTML = "&nbsp;:&nbsp;";
      titleTableRow.appendChild(titleTableCell2);
      var titleTableCell3 = document.createElement('td');
      titleTableCell3.style.fontSize = '8pt';
      titleTableCell3.id = ARCHIVERS[i].name + "_title_" + this.index;
      titleTableCell3.innerHTML = ARCH_AUCTION_CHECK_IN_PROGRESS;
      titleTableRow.appendChild(titleTableCell3);
      titleTableBody.appendChild(titleTableRow);

      this.mark(this.linkTD); 
      if(ARCHIVERS[i].multi == false) 
      {
        ARCHIVERS[i].check(this);
      }  
    }  
  }
  titleTable.appendChild(titleTableBody);
  this.titleTD.appendChild(titleTable);
}

/////////////////////////////////////////////////////////////////
// Coment filtering/coloring related functions
/////////////////////////////////////////////////////////////////
function changeCommentRowBackgroundColor(element, color, doColoring)
{
  var newColor = doColoring ? color : "";
  var childNodes = getChildNodes(element);
  for(var i=0; i<childNodes.length; i++)
  {
    childNodes[i].style.backgroundColor = newColor;
  }

  // Comments on add feedback page consist of one row only.
  // On other pages each comment has 3 rows - so wee need to color it as well.
  if (isAddFeedbackPage == false)
  {
    var tdArray = getChildNodes(getNextSibling(element, 1));
    if(tdArray)
    {
      for(var i=0; i < tdArray.length; i++)
      {
        tdArray[i].style.backgroundColor = newColor;
      }
    }
    var tdArray = getChildNodes(getNextSibling(element, 2));
    if(tdArray)
    {
      for(var i=0; i < tdArray.length; i++)
      {
        tdArray[i].style.backgroundColor = newColor;
      }
    }
  }
}

function hideComment(row, hide)
{
  if (row)
  {
    var displayValue = hide ? "none" : "";
    row.style.display = displayValue;
    // Comments on add feedback page consist of one row only.
    // On other pages each comment has 2 rows - so wee need to hide/show it as well.
    if (isAddFeedbackPage == false)
    {
      getNextSibling(row, 1).style.display = displayValue;
      getNextSibling(row, 2).style.display = displayValue;
    }
  }
}

function filterComments()
{
  if(COMMENTS)
  {
    var filter  = GM_getValue(AT_FILTER, ALL_BTN);
    var commentTypeFilter  = GM_getValue(AT_COMMENT_TYPE_FILTER, COMMENTS_ALL_BTN);
    var doColoring = GM_getValue(AT_COLORING, false);
    var hideSellers = ((filter == BUYERS_BTN) && showCommentSourceFilter);
    var hideBuyers = ((filter == SELLERS_BTN) && showCommentSourceFilter);
    var hidePositive = ((commentTypeFilter != COMMENTS_ALL_BTN) && (commentTypeFilter != COMMENTS_POSITIVE_BTN) && showCommentTypeFilter);
    var hideNeutral = ((commentTypeFilter != COMMENTS_ALL_BTN) && (commentTypeFilter != COMMENTS_NEUTRAL_BTN) && showCommentTypeFilter);
    var hideNegative = ((commentTypeFilter != COMMENTS_ALL_BTN) && (commentTypeFilter != COMMENTS_NEGATIVE_BTN) && showCommentTypeFilter);
    var id = false;
    var hide  = false;
    var visibleCount = 0;
    var color = false;
    for(var i = 0; i < COMMENTS.length; i++)
    {
      id = COMMENTS[i].getAttribute("id");
      hide = false;
      
      // Check seller/buyer
      if (id.match(SELLER_STRING))
      {
        hide = hideSellers;
        color = SELLER_COLORS[visibleCount % 2];
      }  
      else if (id.match(BUYER_STRING))
      {
        hide = hideBuyers;
        color = BUYER_COLORS[visibleCount % 2];
      }

      // Check positive/neutral/negative
      if (id.match(POSITIVE_STRING))
      {
        hide = (hide || hidePositive);
      }  
      else if (id.match(NEUTRAL_STRING))
      {
        hide = (hide || hideNeutral);
      }  
      else if (id.match(NEGATIVE_STRING))
      {
        hide = (hide || hideNegative);
      }

      // If row displayed - do coloring
      if(hide == false)
      {
        changeCommentRowBackgroundColor(COMMENTS[i], color, doColoring)
        visibleCount++;
      }

      hideComment(COMMENTS[i], hide);
    }
  }
}

function displayThumbnails(display)
{
  var displayValue = display ? "" : "none";
  var element = null;
  var commentCount = 0;
  while ((element = document.getElementById("_thumbnail_" + commentCount)) != null)
  {
    element.style.display = displayValue;
    commentCount++;
  }
  var headerCount = 0;
  while ((element = document.getElementById("_thumbnail_header_" + headerCount)) != null)
  {
    element.style.display = displayValue;
    headerCount++;
  }
}

/////////////////////////////////////////////////////////////////
// Menu related functions
/////////////////////////////////////////////////////////////////
function showButton(id, show)
{
  var displayValue = show ? "block" : "none";
  var element = document.getElementById(id);
  if(element && element.style.display != displayValue)
  {
    element.style.display = displayValue;
  }
}

function enableButton(id, enable)
{
  var element = document.getElementById(id);
  if(element && element.disabled != !enable)
  {
    element.disabled = !enable;
  }
}

function isEnabledButton(id)
{
  var element = document.getElementById(id);
  if(element)
  {
    return !element.disabled;
  }
  else
  {
    return false;
  }
}

function setCheckbox(id, checked)
{
  var element = document.getElementById(id);
  if(element && element.checked != checked)
  {
    element.checked = checked;
  }
}

function getCheckbox(id)
{
  var element = document.getElementById(id);
  if(element)
  {
    return element.checked;
  }
  else
  {
    return false;
  }
}

function getButtonHtml(title, help, id, visible)
{
  return "<td><input style=\"font-size=8pt\" title=\"" + help + "\" type=\"button\" id=\"" + id + "\" value=\"" + title +"\"/></td>";
}

function getCheckboxHtml(title, help, id)
{
  return "<td><input style=\"font-size=8pt\" title=\"" + help + "\" type=\"checkbox\" id=\"" + id + "\"/><label style=\"font-size=8pt\" title=\"" + help + "\" for=\"" + id + "\">" + title + "</label></td>";
}

function addMenu()
{
  var menuPosition = document.getElementById("flpw");
  if(menuPosition == null)
  {
    menuPosition = getNextSibling(document.getElementById("myAllegroSubMenu"), 1); // workaround when flpw DIV is missing
  }
  if(menuPosition)
  {
    var menuDiv = document.createElement("div");
    menuDiv.style.backgroundColor="#E7DAD1";
    menuDiv.style.borderTopColor="#002449";
    menuDiv.style.borderTopWidth="4";
    menuDiv.style.borderTopStyle = "solid";
    menuPosition.parentNode.insertBefore(menuDiv, menuPosition);

    if(showCommentTypeFilter)
    {
      var filterCommentTypeMenu = document.createElement("div");
      menuDiv.appendChild(filterCommentTypeMenu);
      filterCommentTypeMenu.innerHTML = "<table cellspacing='2' cellpadding='0' border='0'><tr>" +
                                        getButtonHtml("Wszystkie", "Wyswietla wszystkie komentarze", COMMENTS_ALL_BTN, true) +
                                        getButtonHtml("Pozytywne", "Wyswietla tylko komentarze pozytywne", COMMENTS_POSITIVE_BTN, true) +
                                        getButtonHtml("Neutralne", "Wyswietla tylko komentarze neutralne", COMMENTS_NEUTRAL_BTN, true) +
                                        getButtonHtml("Negatywne", "Wyswietla tylko komentarze negatywne", COMMENTS_NEGATIVE_BTN, true) +
                                        "</tr></table>";
      var commentTypeFilter  = GM_getValue(AT_COMMENT_TYPE_FILTER, COMMENTS_ALL_BTN);
      enableButton(COMMENTS_ALL_BTN, (commentTypeFilter != COMMENTS_ALL_BTN));
      enableButton(COMMENTS_POSITIVE_BTN, (commentTypeFilter != COMMENTS_POSITIVE_BTN));
      enableButton(COMMENTS_NEUTRAL_BTN, (commentTypeFilter != COMMENTS_NEUTRAL_BTN));
      enableButton(COMMENTS_NEGATIVE_BTN, (commentTypeFilter != COMMENTS_NEGATIVE_BTN));
      registerEventHandler(document.getElementById(COMMENTS_ALL_BTN), "click", handleCommentsAllButton);
      registerEventHandler(document.getElementById(COMMENTS_POSITIVE_BTN), "click", handleCommentsPositiveButton);
      registerEventHandler(document.getElementById(COMMENTS_NEUTRAL_BTN), "click", handleCommentsNeutralButton);
      registerEventHandler(document.getElementById(COMMENTS_NEGATIVE_BTN), "click", handleCommentsNegativeButton);
    }

    var filterBuyerSellerMenu = document.createElement("div");
    menuDiv.appendChild(filterBuyerSellerMenu);
    var filterBuyerSellerMenuInnerHTML = "<table cellspacing=2 cellpadding=0 border=0>";
    if(showCommentSourceFilter)
    {
      filterBuyerSellerMenuInnerHTML = filterBuyerSellerMenuInnerHTML +
                                       getButtonHtml("Wszyscy", "Wyswietla kupujacych i sprzedajacych", ALL_BTN, true) +
                                       getButtonHtml("Sprzedajacy", "Wyswietla tylko sprzedajacych", SELLERS_BTN, true) +
                                       getButtonHtml("Kupujacy", "Wyswietla tylko kupujacych", BUYERS_BTN, true) +
                                       "<td>&nbsp;</td>";
    }                                    
    filterBuyerSellerMenuInnerHTML = filterBuyerSellerMenuInnerHTML +
                                     getCheckboxHtml("Kolorowanie", "Wlacza/wylacza kolorowanie kupujacych/sprzedajacych", COLORING_CHBX) +
                                     "<td>&nbsp;</td>";
    if(isAddFeedbackPage == false)
    {
      filterBuyerSellerMenuInnerHTML = filterBuyerSellerMenuInnerHTML +
                                       getCheckboxHtml("Miniaturki", "Wlacza/wylacza wyswietlanie minaturek zdjec przedmiotow", THUMBNAILS_CHBX) +
                                       "<td>&nbsp;</td>" +
                                       getCheckboxHtml("Autosprawdzanie", "Wlacza/wylacza automatyczne sprawdzanie aukcji. Sprawdzane sa archiwa: Allegro, Archi-Wizator, Allegromat i PPA. Gdy wlaczona jest ta opcja, przycisk sprawdz aukcje jest niedostepny", AUTOCHECK_CHBX) +
                                       "<td>&nbsp;</td>" +
                                       getButtonHtml("Sprawdz aukcje", "Sprawdza aukcje wyswietlane na tej stronie. Sprawdzane sa archiwa: Allegro, Archi-Wizator, Allegromat i PPA. Jesli przycisk ten jest wylaczony, oznacza to ze aukcje na tej stronie zostaly juz sprawdzone lub sprawdzanie jest w toku", CHECK_LINKS_BTN);

      var archiverMenu = document.createElement("div");
      menuDiv.appendChild(archiverMenu);
      var archiverMenuInnerHTML = "<table cellspacing='2' cellpadding='0' border='0'><tr>" +
                                  "<td style=\"font-size=8pt\">Sprawdz archiwa:</td>" +
                                  "<td>&nbsp;</td>";
      for(var i = 0; i < ARCHIVERS.length; i++)
      {
        archiverMenuInnerHTML = archiverMenuInnerHTML +
                                getCheckboxHtml(ARCHIVERS[i].name, "Wlacza/wylacza sprawdzanie archiwum " + ARCHIVERS[i].name + " (UWAGA! zmiany tej opcji beda widoczne dopiero po nastepnym odswiezeniu strony!)", ARCHIVERS[i].name + ARCH_CHBX) +
                                "<td>&nbsp;</td>";
      }                           
      archiverMenuInnerHTML = archiverMenuInnerHTML +
                              "<td>&nbsp;</td>" +
                              getCheckboxHtml("Pokazuj niezarchiwizowane", "Wlacza/wylacza wyswietlanie archiwow nie posiadajacych zarchiwizowanej aukcji (UWAGA! zmiany tej opcji beda widoczne dopiero po nastepnym odswiezeniu strony!)", SHOW_EMPTY_ARCH_CHBX) +
                              "</tr></table>";
      archiverMenu.innerHTML = archiverMenuInnerHTML;
    }
    filterBuyerSellerMenuInnerHTML = filterBuyerSellerMenuInnerHTML +
                                     "</tr></table>";
    filterBuyerSellerMenu.innerHTML = filterBuyerSellerMenuInnerHTML;
    if(showCommentSourceFilter)
    {
      var filter  = GM_getValue(AT_FILTER, ALL_BTN);
      enableButton(ALL_BTN, (filter != ALL_BTN));
      enableButton(SELLERS_BTN, (filter != SELLERS_BTN));
      enableButton(BUYERS_BTN, (filter != BUYERS_BTN));
      registerEventHandler(document.getElementById(ALL_BTN), "click", handleAllButton);
      registerEventHandler(document.getElementById(SELLERS_BTN), "click", handleSellersButton);
      registerEventHandler(document.getElementById(BUYERS_BTN), "click", handleBuyersButton);
    }
    var coloring = GM_getValue(AT_COLORING, false);
    setCheckbox(COLORING_CHBX, coloring);
    registerEventHandler(document.getElementById(COLORING_CHBX), "click", handleColoringCheckbox);


    if(isAddFeedbackPage == false)
    {
      setCheckbox(THUMBNAILS_CHBX, GM_getValue(AT_THUMBNAILS, true));
      var autocheck = GM_getValue(AT_AUTOCHECK, false);
      setCheckbox(AUTOCHECK_CHBX, autocheck);
      showButton(CHECK_LINKS_BTN, !autocheck);
      registerEventHandler(document.getElementById(THUMBNAILS_CHBX), "click", handleThumbnailsCheckbox);
      registerEventHandler(document.getElementById(AUTOCHECK_CHBX), "click", handleAutocheckCheckbox);
      registerEventHandler(document.getElementById(CHECK_LINKS_BTN), "click", handleCheckLinksButton);

      var showEmpty = GM_getValue(AT_SHOW_EMPTY_ARCH, true);
      setCheckbox(SHOW_EMPTY_ARCH_CHBX, showEmpty);
      registerEventHandler(document.getElementById(SHOW_EMPTY_ARCH_CHBX), "click", handleShowEmptyArchCheckbox);
      for(var i = 0; i < ARCHIVERS.length; i++)
      {
        setCheckbox(ARCHIVERS[i].name + ARCH_CHBX, ARCHIVERS[i].enabled);
        registerEventHandler(document.getElementById(ARCHIVERS[i].name + ARCH_CHBX), "click", function(e){handleArchCheckbox(e);});
      }
    }
  }                           
}

function insertThumbnailTD(row, count, header)
{
  // Insert thumbnail cell
  var thumbnailTD = document.createElement("TD");
  if(header == false)
  {
    thumbnailTD.rowSpan = '3';
    thumbnailTD.width = "70";
    thumbnailTD.height = "54";
    thumbnailTD.style.verticalAlign = "middle";
    thumbnailTD.style.align = "center";
    thumbnailTD.align = "center";
    thumbnailTD.innerHTML = "<font font-size='8pt' color='#888888'><center>brak</center></font>";
    thumbnailTD.id = "_thumbnail_" + count;
  }
  else  
  {
    thumbnailTD.innerHTML = "Zdjecie";
    thumbnailTD.id = "_thumbnail_header_" + count;
  }
  thumbnailTD.style.display = "none";
  var location = null; 
  if((isAddFeedbackPage) || (isRecvdFeedbackPage))
  {
    location = select(row, 1);
  }
  else
  {
    location = select(row, 0);
  }  
  if(location)
  {
    thumbnailTD.className = location.className;
    row.insertBefore(thumbnailTD, location);
  } 
}         

/////////////////////////////////////////////////////////////////
function findComments()
{
  var tables = document.getElementsByTagName("table");
  var commentRows = false;
  // First find tables with comments
  for (var i = 0; i < tables.length; ++i)
  {
    node = tables[i];
    classAttr = node.className;
    if((classAttr) && (classAttr == "list-head"))
    {
      COMMENT_TABLE = node;
      commentRows = COMMENT_TABLE.rows;
      break;
    }
  }
  
  // Now group seller and buyer comments also mark positive/neutral/negative comments
  if (commentRows)
  {
    var row;
    var commentCount = 0;
    var headerCount = 0;
    for(var i=0; i < commentRows.length; i++)
    {
      row = commentRows[i];
      if(row && (getChildNodes(row).length > 1)) // check length to skip comment text rows
      {
        var cell, commentTypeCell;
        var id = "";

        // Mark buyer seller
        if(isAddFeedbackPage)
        {
          cell = select(row, 2);
        }
        else if(isRecvdFeedbackPage)
        {
          cell = select(row, 1);
        }
        else
        {
          cell = getFirstChild(row);
        }
        if(cell)
        {
          var string = getInnerText(cell);
          // TODO correct matching strings
          if(string.match(SELLER_STRING))
          {
            id = id.concat(SELLER_STRING);
          }  
          else if(string.match(BUYER_STRING))
          {
            id = id.concat(BUYER_STRING);
          }
        }

        if (showCommentTypeFilter)
        {
          if(isRecvdFeedbackPage)
          {
            commentTypeCell = select(row, 2, 0);
          }
          else
          { 
            commentTypeCell = select(row, 1, 0);
          }  
          if(commentTypeCell)
          {
            var commentTypeString = getInnerText(commentTypeCell);
            if(commentTypeString.match(POSITIVE_STRING))
            {
              id = id.concat(POSITIVE_STRING);
            }
            else if(commentTypeString.match(NEUTRAL_STRING))
            {
              id = id.concat(NEUTRAL_STRING);
            }
            else if(commentTypeString.match(NEGATIVE_STRING))
            {
              id = id.concat(NEGATIVE_STRING);
            }
          }
        }

        if (id != "")
        {
          row.setAttribute("id", id);
          COMMENTS.push(row);
          if(!isAddFeedbackPage)
          {
            insertThumbnailTD(row, commentCount, false);
            commentCount++;
          }  
        }
        else if ((getFirstChild(row).className == "my-list") && (!isAddFeedbackPage))
        {
          insertThumbnailTD(row, headerCount, true);
          headerCount++;
        }
      }
    }
  }
}

function allegrotoolsComments()
{
  // Initialize at the start, so changes won't affect the processing
  showEmptyArch = GM_getValue(AT_SHOW_EMPTY_ARCH, true);
  
  if((document.location.href.match(/page=feedbacks/) && document.location.href.match(/type=fb_gave/)) ||
     (document.location.href.match(/page=feedbacks/) && document.location.href.match(/type=fb_recvd/)) ||
     (document.location.href.match(/page=feedbacks/) && (document.location.href.match(/type/) == null)))
  {
    showCommentTypeFilter = true;
    showCommentSourceFilter = true;
  }
  else if(document.location.href.match(/type=fb_given_all/))
  {
    showCommentSourceFilter = true;
  }

  if(document.location.href.match(/page=feedbacks/) && document.location.href.match(/type=fb_add/))
  {
    isAddFeedbackPage = true;
  }
  else if(document.location.href.match(/page=feedbacks/) && document.location.href.match(/type=fb_recvd/))
  {
    isRecvdFeedbackPage = true;
  }
  
  findComments();
  if (COMMENT_TABLE)
  {
    filterComments();
    displayThumbnails(GM_getValue(AT_THUMBNAILS, true));
    addMenu();
    autocheckLinks();
  }
}

/////////////////////////////////////////////////////////////////
// Start Allegro Tools Comments script
/////////////////////////////////////////////////////////////////

allegrotoolsComments()

})();
