// ==UserScript==
// @name          EasyNews Search Filter
// @description   Filter and enhance EasyNews search results
// @namespace     http://www.gozer.org/mozilla/greasemonkey/
// @include       http://members.easynews.com/search*
// @include       https://secure.members.easynews.com/search*
// @include       http://members.easynews.com/global*
// @include       https://secure.members.easynews.com/global*
// @include       http://members.easynews.com/idx.html*
// @include       https://secure.members.easynews.com/idx.html*
// @include       http://members.easynews.com/news/*
// @include       https://secure.members.easynews.com/news/*
// ==/UserScript==

var GM_EasyNewsLinkMatch_TYPE_STRING = 0,
    GM_EasyNewsLinkMatch_TYPE_REGEXP = 1;

function GM_EasyNewsLinkMatch(string)
{
  try {
    this.type  = GM_EasyNewsLinkMatch_TYPE_REGEXP;
    this.value = new RegExp(string, 'i');
  } catch(e) {
    this.type  = GM_EasyNewsLinkMatch_TYPE_STRING;
    this.value = string.toLowerCase();
  }
}

GM_EasyNewsLinkMatch.prototype.match = function(link)
{
  var file  = null;
  var text  = link.innerHTML;
  var value = this.value;

  if(!link || !value) {
    GM_log('match(): link or value empty');
    return(false);
  }

  if(link.hasAttribute('href')) {
    var p = link.getAttribute('href').split('/');  // split into path elements
    file = (p.length) ? p[p.length-1] : null;      // match on the file only
  }

  switch(this.type) {
    case GM_EasyNewsLinkMatch_TYPE_STRING:
      file = (file) ? file.toLowerCase() : null;
      text = (text) ? text.toLowerCase() : null;

      return((file && file.indexOf(value) != -1) ||
             (text && text.indexOf(value) != -1));
    case GM_EasyNewsLinkMatch_TYPE_REGEXP:
      return((file && value.test(file)) || (text && value.test(text)));
    default:
      break;
  }

  GM_log('match(): unknown type: ' + this.type);

  return(false);
}

function GM_EasyNewsLinkColor(color, regexp)
{
  this.color = color;

  try {
    this.value = new RegExp(regexp, 'i');
  } catch(e) {
    this.value = null;
  }
}

GM_EasyNewsLinkColor.prototype.match = function(string)
{
  return((this.value) ? this.value.test(string) : false);
}

// http://www.mozdev.org/bugs/show_bug.cgi?id=12838

function GM_EasyNews_getPref(prefName, defaultValue)
{
  var retval;
  try {
    retval = GM_getValue(prefName, defaultValue);
  } catch(e) {
    retval = defaultValue;
  }

  if(retval == undefined)
    return(null);

  return(retval);
}

function GM_EasyNews_setPref(prefName, value)
{
  try {
    GM_setValue(prefName, value);
  } catch(e) { }
}

// --- initialization ---------------------------------------------------------

var GM_EasyNews_colorMap = [
    [ '#4682b4', '\\.(nfo|txt|sfv|crc|cue)$'       ], // slate blue
    [ '#20b2aa', '\\.par2?$'                       ], // light sea green
    [ '#6b8e23', '\\.nzb$'                         ], // olive drab
    [ '#9932cc', '\\.(jpe?g|png|gif|bmp)$'         ], // dark orchid
    [ '#9370db', '\\.(mpe?g|avi|wmv|mov|rm)$'      ], // medium purple
    [ '#c71585', '\\.(mp3|wav|wma|ra)$'            ], // medium violet red
    [ '#8b008b', '\\.(m3u|pls|ram|b4s|asx)$'       ], // magenta4
    [ '#8b0000', '\\.(tgz|gz|bz2|r(ar|[0-9]{2}))$' ], // dark red
    [ '#daa520', '\\.zip$'                         ], // goldenrod
    [ '#32cd32', '\\.(exe|com|pif|bat|sh|bin)$'    ]  // lime green
  ];

var colorMap = [ ];

for(var i = 0; i < 25; i++) {
  var p = GM_EasyNews_getPref('color' + (i+1));
  var c = (p) ? p.match('^(#[A-Za-z0-9]{3,6})\\|(.*)$') : null;

  if(c && c.length == 3 && c[2]) {
    var e = new GM_EasyNewsLinkColor(c[1], c[2]);

    if(e && e.value)
      colorMap.push(e);
  }
}

// first run, save defaults
if(GM_EasyNews_getPref('colorize') == null && !colorMap.length) {
  GM_EasyNews_setPref('colorize', true);

  for(var i = 0; i < GM_EasyNews_colorMap.length; i++) {
    var c = GM_EasyNews_colorMap[i];
    var e = new GM_EasyNewsLinkColor(c[0], c[1]);

    if(e && e.value) {
      colorMap.push(e);
      GM_EasyNews_setPref('color' + colorMap.length, c[0] + '|' + c[1]);
    }
  }

  GM_EasyNews_setPref('AutoUnRAR', '#ff0000'); // red
}

// --- colorize matching links ------------------------------------------------

// mark AutoUnRAR and other important (file type) links

if(GM_EasyNews_getPref('colorize') == true) {
  var links = document.getElementsByTagName('a');

  var news = new RegExp('\\/news\\/');

  var auto = GM_EasyNews_getPref('AutoUnRAR');

  if(auto && !auto.match('^#[A-Za-z0-9]{3,6}$'))
    auto = null;

  for(var i = 0; i < links.length; i++)
    if(links[i].hasAttribute('href')) {
      var href = links[i].getAttribute('href');

      // process only /news/ links
      if(news.test(href)) {
        // remove the extraneous target attribute for file links, which
        // causes the browser to open a new window for a downloadable.
        // there's a pref, but is not working... (?)
        /*if(links[i].hasAttribute('target') && links[i].target == 'subjTarget')
          links[i].removeAttribute('target');*/

        // really make AutoUnRAR links stand out
        if(links[i].innerHTML.indexOf('AutoUnRAR') != -1) {
          links[i].style.fontWeight = 'bold';
          links[i].style.fontStyle = 'italic';

          if(auto)
            links[i].style.color = auto;

          continue;
        }

        for(var x = 0; x < colorMap.length; x++)
          if(colorMap[x].match(href)) {
            links[i].style.color = colorMap[x].color;
            break;
          }
      }
    }
}

// http://members.easynews.com/search.html frequently displays results
// which match on poster data, making some searches almost impossible
// to weed through. this will display only results which match on the
// subject or filename.

var string = document.location.href.match('[?&]search=([^&]+)&?');
var forms = document.getElementsByTagName('form');

if(string && forms.length) {
  var patterns = unescape(string[1]).split(' ');

  for(var i = 0; i < patterns.length; i++)
    patterns[i] = new GM_EasyNewsLinkMatch(patterns[i]);

  var tables = forms[0].getElementsByTagName('table');

  for(var i = 0; i < tables.length; i++) {
    var links = tables[i].getElementsByTagName('a');

    if(links.length && links[0].hasAttribute('href'))
      for(var x = 0; x < patterns.length; x++)
        if(!patterns[x].match(links[0])) {
          tables[i].style.display = 'none';
          break;
        }
  }
}
