search = {}; // namespace object
var markers = [];
var tearIcon, boxIcon;
var labels = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';

// in the first argument to TagNode, the href: field is used to specify
// the "title" of the node
/**
 * Initialize the yui tree.
 * @param div where to display the yui tree
 * @param tags: object w/ fields spots, areas, interests, each an array of data for the S, A, and I tags.
 * Each data element (as returned from JsHelper::atags() etc) contains:
 * id, label, parentId, what, childrenPresent, prefValue.
 */
search.buildtree = function(div, tags) {
  tagData = tagTree.build(tags);
  search._tree = new YAHOO.widget.TreeView(div);
  var root = search._tree.getRoot();
  if (tagData.spots) { search._addNodes(root, tagData.spots); }
  if (tagData.areas) { search._addNodes(root, tagData.areas); }
  if (tagData.interests) { search._addNodes(root, tagData.interests); }
  search._tree.draw();
};

/**
 * Walk the the tagTree, and add each node to the yui tree.
 * @param root root node of yui tree
 * @param dataNode root node of tagTree
*/
search._addNodes = function(root, dataNode) {
  if (dataNode.data.prefValue[0] == 0) { return; } // don't show it at all if 0 unchecked
  var isTop = (dataNode.data.id <= 0);
  var parent = (isTop ? root : dataNode.parent.yuiNode);
  dataNode.yuiNode = new YAHOO.widget.TagNode(
      dataNode.yuiData(), // data
      parent, // parent in yui tree
      false, //expanded
      !isTop); //add other/unspecified sibling (not top)
  dataNode.yuiNode.setCheckState(dataNode.data.prefValue[1]);
  for (var i = 0; i < dataNode.children.length; i++) {
    search._addNodes(root, dataNode.children[i]);
  }

};

function checkAll() {
  var topNodes = search._tree.getRoot().children;
  for(var i=0; i<topNodes.length; ++i) {
    topNodes[i].check();
  }
}

function uncheckAll() {
  var topNodes = search._tree.getRoot().children;
  for(var i=0; i<topNodes.length; ++i) {
    topNodes[i].uncheck();
  }
}

var myTabs = new YAHOO.widget.TabView("tabs");

// called by search button
function startSearch() {
  myTabs.set('activeIndex', 1);
}

// capture event when tab changes to "results"
function tabChange(e) {
  if (myTabs.getTab(1) == e.newValue) return doSearch();
  return true;
}

myTabs.addListener('beforeActiveTabChange', tabChange);

/** Walk tree, adding data to req. Private fcn. Only add data for leaf nodes. */
search.addReq = function(node, req) {
  if (node.children.length == 0) {
    if (node.checkState == 2) { req.push(node.data.myData.id); }
  } else {
    for (var i = 0; i < node.children.length; i++) {
      search.addReq(node.children[i], req);
    }
  }
};

// AJAX call to return searched-for places
function doSearch() {
  $('results').innerHTML = '<img src="img/loading.gif" alt="loading..." />';
  var root = search._tree.getRoot();
  var req = []; // list of id's of nodes with
  // for each root.children
  for (var i = 0; i < root.children.length; i++) {
    search.addReq(root.children[i], req);
  }
  var tags = '';
  for (var i = 0; i < req.length; i++) {
    tags += req[i] + ',';
  }
  if (tags.length == 0) {
    alert('Nothing selected');
    return false;
  }
  var mine = '0';
  if ($('mineP').checked) mine = "P"; // popular
  else if ($('mineV').checked) mine = "V"; // most votes
  else if ($('mineN').checked) mine = "N"; // newest
  else if ($('mineA').checked) mine = "A"; // most active
  else if ($('mineL').checked) mine = "L"; // most links or comments
  if (mine == '0') {
    alert("invalid search option");
    return false;
  }
  var numid = $('num');
  var numr = numid.options[numid.selectedIndex].value;
  if (numr == 0) numr = 100;
  var bounds = map.getBounds();
  var sUrl = 'lib/ajax/search.php?tags=' + tags.substr(0,tags.length-1) + '&mine=' + mine +
    "&n=" + bounds.getNorthEast().lat() + "&e=" + bounds.getNorthEast().lng() +
    "&s=" + bounds.getSouthWest().lat() + "&w=" + bounds.getSouthWest().lng() +
    "&num=" + numr;
  var trans = YAHOO.util.Connect.asyncRequest('GET', sUrl, sbobj);
  return true;
}

var sbobj = {
 success: searchback,
 failure: function(o) {
  $('results').innerHTML = '*** <i>no matches</i> ***';
  if (markers.length > 0) {
    map.clearOverlays();
    markers = [];
  }
 }
 // argument: [argument1, argument2, argument3]
};

function searchback(o) {
  var m = 0;
  var result = '';
  var lasttag = null;
  var lines = o.responseText.split("\n");
  if (markers.length > 0) {
    map.clearOverlays();
    markers = [];
  }
  for (var ln in lines) {
    if (lines[ln] == '') break;
    var fields = lines[ln].split("\t");
    var place = fields[1];
    var label = (markers[place] == undefined) ? (m < 99) ? m+1 : (m<=519 ? labels.charAt((m-99)/10)+(m-99)%10 : "*") : markers[place].label;
    var args = place + ",'" + label + "'";
    if (fields[7]=='B') args += ", true, " + fields[8] + "," + fields[9] + "," + fields[10] + "," + fields[11];
    if (lasttag && fields[0] != lasttag) result += "<hr style=\"height:1px;background-color:#333;margin-top:2px\" />\n";
    lasttag = fields[0];
    result += "<div class=\"result-"+label+"\" onmouseover=\"hilite("+args+")\" onmouseout=\"unhilite("+args+")\">" +
      label + " <a href=\"pid-" + place + "\" target=\"_blank\">" +
      fields[6] + "</a> " + ' ' + fields[5] + ' ' + rating(fields[4]) + "</div>\n";
    if (markers[place] == undefined) {
      var b = map.getBounds();
        var rl = fields[3];
        var lat = Math.max(Math.min(fields[2],b.getNorthEast().lat()),b.getSouthWest().lat());
        var lng = (b.getSouthWest().lng() < b.getNorthEast().lng()) ?
          Math.max(Math.min(rl,b.getNorthEast().lng()),b.getSouthWest().lng()) :
          ((Math.abs(rl-b.getSouthWest().lng()) < Math.abs(rl-b.getNorthEast().lng())) ?
            Math.max(rl,b.getSouthWest().lng()) : Math.min(rl,b.getNorthEast().lng()));
        var point = new GLatLng(lat,lng);
        var mark = createMarker(point, label, fields[6], fields[1], (fields[7]=='B'?'box':'pin'));
      GEvent.addListener(mark, 'click', new Function("window.open('pid-" + fields[1] + "');"));
      GEvent.addListener(mark, 'mouseover', new Function("hilite("+args+")"));
      GEvent.addListener(mark, 'mouseout', new Function("unhilite("+args+")"));
        map.addOverlay(mark);
        mark.label = label;
        markers[place] = mark;
        m++;
    }
  }
  $('results').innerHTML = result + "<div style=\"margin-left:2em;margin-top:5px;\"><input type=button value=\"Search Again\" onclick=\"startSearch();\" /></div>";
}

// AJAX call to find the location of the current IP address
function findIP() {
  YAHOO.util.Connect.asyncRequest('GET', 'lib/ajax/findIP.php', ipcbo);
}

var ipcbo = {
 success: function(o) {
    var lines = o.responseText.split("\n");
    var code = lines[1].split(':')[1].substr(1,2); // country code
    if (code == 'XX') {
      alert('cannot locate your IP address');
      return;
    }
    var lat = lines[3].split(':')[1];
    var lng = lines[4].split(':')[1];
    var point = new GLatLng(lat, lng);
	map.setCenter(point, 10);
  },
 failure: function(o) { alert('error locating your IP address'); }
};

function rating(v) {
  switch(v) {
   case '-3': return '&darr;&darr;&darr;';
   case '-2': return '&darr;&darr;';
   case '-1': return '&darr;';
   case '0': return '&asymp;';
   case '1': return '&uarr;';
   case '2': return '&uarr;&uarr;';
   case '3': return '&uarr;&uarr;&uarr;';
   case '4': return '&uarr;&uarr;&uarr;&uarr;';
   default: return '';
  }
}



// shape can be pin or box
function createMarker(point, label, title, place, shape) {
  if (shape == null) shape = 'pin';
  var icon = new GIcon(shape == 'box'?boxIcon:tearIcon);
  icon.image = 'marker.php?image=img/markers/'+(shape == 'box'?'box':'pin')+'/red.png&text='+label;
  return new GMarker(point, {icon: icon, title: title});
}

var ph = null; // place highlighted

function hilite(marker, label, isb, mn, ms, me, mw) {
  if (ph) { // clean up if unhilite missed
    // alert('clean up "+ph);
    if (ph.isb) {
      map.removeOverlay(zat.bound);
      markers[ph.marker].setImage("marker.php?image=img/markers/box/red.png&text=" + ph.label);
    } else markers[ph.marker].setImage("marker.php?image=img/markers/pin/red.png&text=" + ph.label);
    var elmsoff = YAHOO.util.Dom.getElementsByClassName('result-'+ph.label, 'div', 'results');
    for (var en in elmsoff) elmsoff[en].style.backgroundColor='white';
  }
  if (isb) {
    zat.bound = new BoundPane(mn, ms, mw, me);
    zat.bound.opacity_ = 0.2;
      zat.bound.backgroundColor_ = "#ff2020";
    map.addOverlay(zat.bound);
    markers[marker].setImage("marker.php?image=img/markers/box/black.png&text=" + label + "&color=red");
  } else {
      markers[marker].setImage("marker.php?image=img/markers/pin/black.png&text=" + label + "&color=red");
    }
  var elms = YAHOO.util.Dom.getElementsByClassName('result-'+label, 'div', 'results');
//  for (var en in elms) { elms[en].style.backgroundColor='#ffD0D0'; } // ZAT_TODO: why try to do it this way??
  for (var en = 0; en < elms.length; en++) { elms[en].style.backgroundColor='#ffD0D0'; }
  ph = { isb: isb, marker: marker, label: label };
}

function unhilite(marker, label, isb) {
  if (isb) {
    map.removeOverlay(zat.bound);
    markers[marker].setImage("marker.php?image=img/markers/box/red.png&text=" + label);
  } else markers[marker].setImage("marker.php?image=img/markers/pin/red.png&text=" + label);
  var elms = YAHOO.util.Dom.getElementsByClassName('result-'+label, 'div', 'results');
//  for (var en in elms) elms[en].style.backgroundColor='white';
  for (var en = 0; en < elms.length; en++) elms[en].style.backgroundColor='white';
  ph = null;
}
