/*
<!-- Called with:

       list=NAME                Sort building list by name
       list=CODE                Sort building list by building code
       list=anything else       Don't include a building list

       show=bc1[,bc2...]        comma-delimited set of building codes to show

       width=N                  N = number of pixels of width of the base map
-->
*/

function init() {

   if (is_nav5up) {
      document.all = document.getElementsByTagName("*");
   }
   if (document.layers  &&  !document.all) {
      document.all = document.layers;
   }

   // defineOverlayObjects must be called after the document is loaded
   // so that the HTML elements exist.
   defineOverlayObjects();

   // If the URL specifies a set of buildings to show, then highlight them.
   if (request.show) {
      var s = request.show.toUpperCase() + ",";
      while (s) {
         var i = s.indexOf(",");    // Always ends in a comma!
         var bc = s.substr(0,i);    // Will be a null string if consecutive commas
         pp(bc);
         s = s.substr(i+1);
      }
   }
}

function MapResize() {
   //document.reload();
   //window.location.reload();
   history.go(0);
   return true;
}


/*
 * BC -- constructor for the BC object
 *
 * This object represents a building.  One object is created for
 * each building.
 */
function BC(bcode, name, htop, hleft, pleft, ptop, relative, poly) {
   this.bcode = bcode;     // Building code as assigned by Facilities
   this.name  = name;      // Complete building name
   this.htop  = htop;      // Pixel coordinate of the top edge of the highlighted building...
   this.hleft = hleft;     // ...and the corresponding left edge coordinate.
   this.ptop  = ptop;      // Pixel coordinate of the top edge of the popup building label...
   this.pleft = pleft;     // ...and the corresponding left edge coordinate.
                           // Note: Pixel coordinates are relative to the top left corner of the
                           // base map, and are scaled for the template basemap size.
   this.relative = relative || "LT";
   this.poly  = poly;      // An array of X,Y coordinates for the polygon client-side image map.
}


function handleParameters() {

   listorder = "";                        // Global Variable!

   if (request.list) {
      if (request.list.toUpperCase()=='NAME') {
         listorder = 'NAME';
      }
      if (request.list.toUpperCase()=='CODE') {
         listorder = 'CODE';
      }
   }
}


/*
 * calcScaleFactors -- calculate the size of the base map based on screen size
 *
 * inputs:
 *    request.width -- width specifed on the URL
 *    listorder     -- specified if a listing of building names or codes is to be displayed
 *    listwidth     -- number of pixels wide each panel of building names
 *    templatex, templatey -- size of the template's images and coordinates
 *
 * outputs:
 *    basemapx, basemapy  -- width and height of the map image
 *    scalefactor   -- factor to scale the template images to this page's size
 */
function calcScaleFactors() {
   // Figure out how big to make the map
   var iw = 0;
   if (request.width) {
      iw = parseInt(request.width);  // returns 0 if an invalid number
   }
   if (iw==0) {
      // The user didn't specify, or specified wrong
      iw = xbGetWindowWidth();
      if (listorder) {
         iw = iw - 2 * listwidth;
      }
   }
   basemapx = 760;
   if (iw >= 860) {
      basemapx = 860;
   }
   if (iw >= 980) {
      basemapx = 980;
   }
   if (iw >= 1200) {
      basemapx = 1200;
   }
   if (iw >= 1500) {
      basemapx = 1500;
   }
   if (iw >= 2048) {
      basemapx = 2048;
   }
   scalefactor = basemapx / templatex;
   basemapy = Math.round(templatey * scalefactor);
}


/*
 * scale -- scale coordinates from template-based values to page-based values
 *
 */
function scale(x) {
   return Math.round(x * scalefactor);
}


/*
 * writeVariableHTML -- output the variable parts of the map page
 *
 * Some parts of the map page are not determined until runtime.
 *
 * The building list is included or not based on parameters in the URL.
 *
 * The IMG tag for the base map is written here because the image used
 * depends on the browser's window size.
 *
 */
function writeVariableHTML(listorder, basemapx, basemapy) {
   BuildingList(listorder);

   document.write('<div id="main" align="center">',
                  '<img name="main" src="manhattan-' + basemapx + '.gif" width="' + basemapx + '" height="' + basemapy +
                  '" border="0" alt="" usemap="#manhattan">' +
                  '</div>'
                 );
   if (listorder) {
      // Finish off the hanging table structure
      document.write('</td></tr></table>');
   }
}


function offBuildings() {
   for (var i = 0; i < onBuildings.length; i++) {
      var bc = onBuildings[i].bcode;
      H[bc].hide();
      // used in no-popup cases
      if(L[bc] != null) { L[bc].hide(); }

      // If a building list is being shown, also un-highlight the building name
      if (listorder) {
         if (document.getElementById) {
            var le = document.getElementById("list"+bc);
            if (le && le.style) {
               le.style.color = ""; // null string means "normal color before JavaScript changes"
            }
         }
      }
   }
   onBuildings = [];
}


/*
 * p -- display the popups for a given building
 *
 * This is the funciton normally used to display the popups for a given building.
 * It first turns off anything currently highlighted, then turns on the new building.
 *
 * If the building code is a null string, no building is highlighted.
 *
 */
function p(bc) {

   // If the building to be highlighted is already highlighted, ignore
   // the request.  [Needed? -- perhaps this reduces flicker?]
   if (bc==currentbcode) {
      return;
   }

   offBuildings();

   pp(bc);
}


/*
 * pp -- display the popups for a given building
 *
 * The pp function does the grunt work of displaying the popups for a given building.
 * The difference between this function and the p function above is that the p
 * function turns off previously highlighted buildings, and pp doesn't.
 * As a result, if multiple buildings must be highlighted, pp must be used rather than p.
 *
 */
function pp(bc) {

   currentbcode = bc;

   if (bc=="")
      return;

   // If there is a highlight object available, show it.
   if (H[bc]) {
      if (document.images['i'+bc]) {
         // NS 4.x doesn't put dynamically-generated HTML content into the DOM.  So NS 4.x
         // must preload all the images.
         document.images['i'+bc].src = 'buildings/'+bc+'/highlighted-'+basemapx+'.gif';
      //} else {
      //   if (document.layers && document.layers['h'+bc] && document.layers['h'+bc].images['i'+bc]) {
      //      document.layers['h'+bc].images['i'+bc].src = 'buildings/'+bc+'/highlighted-'+basemapx+'.gif';
      //   }
      }
      H[bc].show();
   }

   // If there is a label object available, show it.
   if (L[bc]) {
      if (L[bc].element.style  &&  typeof(L[bc].element.style.filter)=="string") {
         // Only IE keeps a string filter property
         L[bc].element.style.filter = "progid:DXImageTransform.Microsoft.Alpha(opacity=80)";
      }
      L[bc].show();
   }

   // If a building list is being shown, also highlight the building name
   if (listorder) {
      if (document.getElementById) {
         var le = document.getElementById("list"+bc);
         if (le) {
            le.style.color = "red";
         }
      }
   }

   //onBuildings.push(B[bc]);
   // IE 5.0 doesn't support push...
   onBuildings[onBuildings.length] = B[bc];
}


function q() {
   //H['A'].allOff();
}


function hndClick(e) {
    p('');
    return true;
}

function hndMouseDown(e) {
    p('');
    return true;
}


/*
 * parseRequest -- parse the parameters specified in the URL into a "request" object
 *
 * This function returns an object that has a property for each parameter
 * in the URL.  The value of the property is the value as specified in the
 * URL.  For example, with the URL "whatever.html?dog=Max&cat=Saturn",
 * the object returned would have two properties:
 *
 *    request.dog = "Max" and request.cat="Saturn".
 *
 * The returned object is typically named "request", and is modelled after the
 * Server-Side JavaScript "request" object.
 *
 * Note: No facility is available to handle parameters that are specified
 * multiple times.  The last value specified on the URL is the one returned.
 */
function parseRequest(s) {
   var request = new Object();

   // Strip the leading question mark
   if (s.substr(0,1) == '?') {
      s = s.substr(1);
   }

   // Split the query/search string into "name=value" strings.
   var a = s.split(/&/);

   // For each string, split into the name and value, and assign to
   // the request object.
   for (var i = 0; i < a.length; i++) {
      var v = a[i].match(/^([^=]*)=(.*)$/);
      if (v) {
         request[v[1]] = unescape(v[2]);
      }
   }

   return request;
}


/*
 * BuildingList -- write the HTML for a building list
 *
 * The parameter ORDER specifies the order
 *
 * If the ORDER parameter is not null, then this function leaves an
 * unclosed TABLE element that must be closed elsewhere.
 */
function BuildingList(order) {

   if (!order) {
      // If the ORDER parameter is null, there isn't supposed to be a building list,
      // so just return.
      return;
   }

   // Copy the building name and code info into an array so we can sort it.
   s = new Array();
   var i = 0;
   if (order=='NAME') {
      for (var bc in B) {
         s[i++] = B[bc].name + '!' + bc;
      }
   }
   if (order=='CODE') {
      for (var bc in B) {
         s[i++] = bc + '!' + B[bc].name;
      }
   }
   s.sort();

   var col = 1;
   var tempstr = '<table border="0"><tr valign="top"><td width="' + listwidth + '" class="buildinglist">';
   for (var i=0; i<s.length; i++) {
      var a = s[i].split(/!/);
      if (listorder=='NAME') {
         var bc = a[1];
         var label = a[0];
      } else {
         var bc = a[0];
         var label = bc + ' (' +a[1] + ')';
      }
      tempstr += '<a href="buildings/' + bc + '/" onMouseOver="p(\''+bc+'\');" onFocus="p(\''+bc+'\');" ID="list'+bc+ '" name="list'+bc + '">' + label + "</a><br />";
      if (col==1  &&  i >= buildingcount/2+2) {
         col = 2;
         tempstr += '</td><td width="' + listwidth + '" class="buildinglist">';
      }
   }
   document.write(tempstr,
                  '</td>',
                  '<td width=' + basemapx + '>'
                 );
}


/* defineOverlayElements -- create the HTML elements for the popup objects
 *
 * This function writes the HTML for the popup objects that appear on top of the base map
 * Each building has two popup objects.  First, the "building highlight" popup is the
 * section of the map, with the building highlighted, that appears on top of the
 * main map.
 *
 * The second popup object is the "building label", the box with the building's name.
 */

function writeOverlayElements() {
   var tempstr = '';
   for (var bc in B) {
      if (document.layers) {
         // NS 4.x doesn't put dynamically-generated HTML content into the DOM.  So NS 4.x
         // must preload all the images.
         tempstr += '<div id="h' + bc + '" class="popup"><a href="buildings/'+bc+'/"><img src="buildings/'+bc+'/highlighted-'+basemapx+'.gif" name="i' + bc + '" border="0" /></a></div>\n';
         //tempstr += '<div id="h' + bc + '" class="popup"><a href="buildings/'+bc+'/"><img src="/images/transparent-dot.gif" name="i' + bc + '" border="0" /></a></div>\n';
         tempstr +=
            '<div id="l' + bc + '" class="popup"><table border="0" cellspacing="0" cellpadding="2"><tr><td bgcolor="#000000">' +
            '<table border="0" cellspacing="0" cellpadding="6" bgcolor="#f0f0a0">' +
            '<tr align="center">' +
            '<td><div class="popupboxns4">'+
            B[bc].name +
            '</div></td>' +
            '</tr></table>' +
            '</td></tr></table></div>\n';
      } else {
         //tempstr += '<div id="h' + bc + '" class="popup"><a href="buildings/'+bc+'/"><img src="buildings/'+bc+'/highlighted-'+basemapx+'.gif" name="i' + bc + '" border="0" /></a></div>\n' +
         tempstr += '<div id="h' + bc + '" class="popup"><a href="buildings/'+bc+'/"><img src="/images/transparent-dot.gif" name="i' + bc + '" border="0" /></a></div>\n' +
            '<div id="l' + bc + '" class="popup"><div class="popupbox">' + B[bc].name + '</div></div>\n';
      }
   }
   document.writeln(tempstr);

   // Now that the HTML elements exist, you'd think that we could call defineOverlayObjects to
   // create the corresponding JavaScript objects.  However, the browser hasn't necessarily parsed
   // and processed the HTML yet.  So defineOverlayObjects is called in the onLoad event handler.
}


function defineOverlayObjects() {
   H = new Object();
   L = new Object();
   for (var bc in B) {
      H[bc] = new MapPopup("h"+bc, scale(B[bc].hleft)-1, scale(B[bc].htop)-1, 2, document.images["main"]);
      if (B[bc].pleft != 0  && B[bc].ptop != 0) {
         L[bc] = new MapPopup("l"+bc, scale(B[bc].pleft)-1, scale(B[bc].ptop)-1, 2, document.images["main"], B[bc].relative);
      }
   }
}


function writeClientSideImageMap(B, scalefactor) {

   // If the URL specifies a building to show, then there is no need for a client-side image map.
   if (request.show)
      return;

   var tempstr;
   var poly;
   document.writeln('<map name="manhattan">');
   for (var bc in B) {
      if (B[bc].poly) {
         tempstr = '<area shape="polygon" coords="';
         poly = B[bc].poly;
         for (var i = 0; i < poly.length; i=i+2) {
            tempstr += Math.round(scalefactor * poly[i]  ) + ',' +
                       Math.round(scalefactor * poly[i+1]);
            if (i+2 < poly.length) {
               // This isn't the last entry in the list, so add a comma
               tempstr += ",";
            }
         }
         document.writeln(tempstr, '" href="buildings/' + bc + '/" onmouseover="p(\''+bc+'\');" onfocus="p(\''+bc+'\');" onmouseout="q();">');
      }
   }
   document.writeln('<area shape="default" href="javascript:void()" onmouseover="p(\'\');"></map>');
}


/*
 * writeInstructions -- produce the instructions at the top of the map.
 *
 * This function produces customized instructions for the top of the map.  In particular,
 * if the interactive map is in effect, it says to move the mouse pointer of the image.
 * If a building is highlighted, then the message indicates that this building is selected.
 */
function writeInstructions() {
   var instructions;

   if (request.show) {
      instructions = "This map highlights one or more specific buildings.<br />" +
                     "For details, click on a highlighted building." +
                     "<br /><br />An <a href=\"index.html\">interactive map</a> that can highlight all buildings is also available."
      ;
   } else {
      instructions = "For the building name, move the mouse pointer over the building.<br />" +
                     "For details, click on a highlighted building."
      ;
   }

   document.writeln("<p class=\"instructions\">" + instructions + "</p>");

}
