var Utils = {};

Utils.join = function(sep, ary) {
  var result = '';
  var notFirst = false;
  for (var i = 0; i < ary.length; i++) {
    if (notFirst) {
      result += sep;
    } else {
      notFirst = true;
    }
    result += ary[i];
  }
  return result;
};

Utils.ajax = function(method, url, vars, callbackFunction){
  var request = window.XMLHttpRequest ? new XMLHttpRequest() : new ActiveXObject('MSXML2.XMLHTTP.3.0');

  request.open(method, url, true);
  request.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); 

  request.onreadystatechange = function() {
    if (request.readyState == 4 && request.status == 200) {
      if (request.responseText) {
        callbackFunction(request.responseText);
      }
    }
  }
  request.send(vars);
};

Utils.isNetscape6 = document.getElementById && !document.all;

var JSGem = {};

JSGem.generateList = function(response) {
  var gems = response['gems'] || [];
  var text = '';
  for (var i = 0; i < gems.length; i++) {
    var g = gems[i];
    if (!g) continue;
    text += '<li><a href="' + (g.homepage || '#') +
        '" onclick="JSGem.fetchGemSpecs(\'search\',\'name:' + g.name +
        '/version:' + g.version;
    if (g.platform) text += '/platform:' + g.platform;
    text += '\', JSGem.openPopup); return false;"><i>' + g.date + '</i>&nbsp;' + 
        g.name + '-' + g.version + '</a></li>';
  }
  return text;
};

JSGem.createLine = function(name, value) {
  return '<li><strong>' + name + '</strong>: ' + value + "</li>\n";
};

JSGem.openPopup = function(response) {
  var gems = response['gems'] || [];
  if (!gems[0]) return;
  var g = gems[0];
  document.getElementById('popup-title-text').innerHTML = g.name
  var text = '<ul>';
  text += JSGem.createLine('Rubyforge Project', g['rubyforge_project']);
  text += JSGem.createLine('Version', g['version']);
  text += JSGem.createLine('Platform', g['platform']);
  text += JSGem.createLine('Date', g['date']);
  text += JSGem.createLine('Summary', g['summary']);
  text += JSGem.createLine('Description', g['description']);
  text += JSGem.createLine('Homepage', g['homepage'] ? '<a href="' + g['homepage'] + '">' + g['homepage'] + '</a>' : '');
  text += JSGem.createLine('Email', g['email'] ? '<a href="mailto:' + g['email'] + '">' + g['email'] + '</a>' : '');
  text += JSGem.createLine('Authors', Utils.join(', ', g['authors']));
  text += '</ul>'
  document.getElementById('popup-content').innerHTML = text;
  JSGem.dragPopup.open();
};

JSGem.createEmailList = function(response) {
  document.getElementById('emailList').innerHTML = JSGem.generateList(response);
};

JSGem.createLastList = function(response) {
  document.getElementById('lastList').innerHTML = JSGem.generateList(response);
};

JSGem.createSearchList = function(response) {
  document.getElementById('searchList').innerHTML = JSGem.generateList(response);
};

JSGem.createAttributesText = function(response) {
  var attributes = response['attributes'] || [];
  document.getElementById('attributesText').innerHTML = Utils.join(', ', attributes);
};

JSGem.fetchGemSpecs = function(method, args, updater) {
  Utils.ajax('GET', '/json/' + method + '/' + args, null, function(responseText) {
    var response = responseText || '{}';
    response = eval('(' + response + ')');
    updater(response);
 });
};

JSGem.Popup = function(dragClass, objectId) {
  var that = this;
  this.dragClass = dragClass;
  this.popup = document.getElementById(objectId);
  this.x = 0;
  this.y = 0;
  this.dx = 0;
  this.dy = 0;
  this.isDragged = false;

  this.move = function(x, y) {
    that.popup.style.left = x + 'px';
    that.popup.style.top  = y + 'px';
  }

  this.moveEvent = function(e) {
    if (!that.isDragged) return true;
    var cx = Utils.isNetscape6 ? e.clientX : event.clientX;
    var cy = Utils.isNetscape6 ? e.clientY : event.clientY;
    var x = cx - that.dx;
    var y = cy - that.dy;
    if (x < document.body.offsetTop) x = document.body.offsetTop;
    if (x < 0) x = 0;
    if (y < document.body.offsetLeft) y = document.body.offsetLeft;
    if (y < 0) y = 0;
    that.move(x, y);
    return false;
  }

  this.isSelected = function(e) {
    var obj       = Utils.isNetscape6 ? e.target : event.srcElement;
    var topelement = Utils.isNetscape6 ?  'HTML'  :  'BODY';
    while (obj.tagName != topelement && obj.className !=  dragClass) {
      obj = Utils.isNetscape6 ? obj.parentNode : obj.parentElement;
    }
    return obj.className == dragClass;
  }

  this.mousedown = function(e) {
    that.x = Utils.isNetscape6 ? e.clientX : event.clientX;
    that.y = Utils.isNetscape6 ? e.clientY : event.clientY;
    if (that.isSelected(e)) {
      that.isDragged = true;
      that.dx = that.x - that.popup.offsetLeft;
      that.dy = that.y - that.popup.offsetTop;
      document.onmousemove = that.moveEvent;
      return false;
    }
  }

  this.open = function () {
    var sy = Utils.isNetscape6 ?
      window.scrollY :
      document.documentElement.scrollTop + document.body.scrollTop;
    if (that.popup.style.display != 'block') {
      that.popup.style.display = 'block';
      that.move(parseInt(that.popup.style.left || 300), sy + that.y - that.popup.offsetHeight / 2);
    } else {
      that.move(that.popup.offsetLeft, sy + that.y - that.popup.offsetHeight / 2);
    }
  }
  this.close = function () { that.popup.style.display = 'none'; }

  document.onmousedown = this.mousedown;
  document.onmouseup = function() { that.isDragged = false };
}

JSGem.init = function() {
  JSGem.dragPopup = new JSGem.Popup('dragme', 'popup');
  if (document.getElementById("attributesText")) JSGem.fetchGemSpecs('attributes', '', JSGem.createAttributesText);
  JSGem.fetchGemSpecs('email', 'flori@ping.de', JSGem.createEmailList);
  JSGem.fetchGemSpecs('last', 10, JSGem.createLastList);
}
