
    /*
     * Javascript Map Preview code - for my use only - (c) 2006 Ron Phillips, aka Xyloid
     */

    var sMapArr;
    var bPaused = null;
    var mAreas = [];
    var xOffset;
    var yOffset;
    var pv;

    /*
     * Adapted from example code: http://www.helsinki.fi/~jppesone/code/dump_get_params.html
     */
    function _GET() {
	var get = [];
	var query = this.location.search.substring(1);
	if ( query.length > 0 ) {
		var params=query.split("&");
		for (var i=0 ; i<params.length ; i++) {
			var pos = params[i].indexOf("=");
			var name, value;
			if ( pos < 0 ) {
				name = params[i];
				value = null;
			} else {
				name = params[i].substring(0, pos);
				value = params[i].substring(pos + 1);
			}
			get[name] = value;
		}
	}
	return get;
    }

    function InitPreview() {
	var img = document.getElementById('previewmap');
	yOffset = img.offsetTop;
	xOffset = img.offsetLeft;
	tb.caption('Zoom (loading data)');

	pv = document.getElementById('locate');
	if ( pv ) {
		pv.Y = 0;
		pv.onmousedown = PreviewPause;
		pv.onmousemove = PreviewHover;
	}

	/* Setup the update */
	var xmlhttp = new XMLHttpRequest();
	xmlhttp.open('GET', sContinent + '.txt', true);

        /* Parse the areas for the ones we want */
        PreviewParse();

        /* The callback function */
        xmlhttp.onreadystatechange = function() {
            if (xmlhttp.readyState == 4) {
                if (xmlhttp.status == 200) {
                	var sMapText = xmlhttp.responseText;
			var map = document.getElementById('previewmap');
			// Hook the move event now.
			map.onmousemove = PreviewHover;
			map.onmousedown = PreviewPause;
			sMapArr = sMapText.split('\n');
			tb.caption('Zoom');

			// Set the indicator to the center of the map (this gives the preview window the right size)
			var e = [];
			var get = _GET();
			if ( get['x'] && get['y'] ) {
				// The default coordinates are given in the url.
				if ( !bPaused) PreviewPause(e);
				document.LastX = parseInt(get['x'])+1;
				document.LastY = parseInt(get['y'])+1;
			} else {
				// No parameters - just put it in the middle of the map.
				document.LastX = parseInt(img.width/2);
				document.LastY = parseInt(img.height/2);
			}
			PreviewHover(e, true);

			// And move the area list to the bottom of this window.
			var span = document.getElementById('preview');
			tb2.div.style.top = (span.offsetTop + span.offsetHeight + 32) + 'px';

			// Hook the click event on the listbox so we can position the viewfinder.
			var arealist = document.getElementById('areanames');
			arealist.onchange = lstAreaSelect;
		}
            }
        }

        xmlhttp.send('');

    }

    /*
     * Returns the id of the selected item in an option tag.
     * --Xyloid
     */
    function GetSelectedListID(list) {
	if ( !list ) return null;
	var nodes = list.getElementsByTagName('option');
	if ( !nodes ) return null;
        for ( var i = 0; i < nodes.length; i++ ) {
		var option = nodes[i];
		if ( option.selected ) return option.id;
	}
    }

    /*
     * When they click an area in the list, move the indicator to that position.
     */
    function lstAreaSelect(e) {
	var arealist = document.getElementById('arealist');
	var coords = GetSelectedListID(arealist).split(',');
	if ( !bPaused) PreviewPause(e);
	document.LastX = parseInt(coords[0])+1;
	document.LastY = parseInt(coords[1])+1;
	PreviewHover(e, true);
    }

    function PreviewLocate(e) {
	if ( !e ) e = window.event;
	var X; var Y;
	X = TBGetX(e) - xOffset - 1;
	Y = TBGetY(e) - yOffset - 1;
    }

    function TBGetX(e) {
      if (e.pageX) return e.pageX;
      return e.clientX + (document.body.scrollLeft || 0);
      return e.clientX;
    }

    function TBGetY(e) {
      if (e.pageY) return e.pageY;
      return e.clientY + (document.body.scrollTop || 0) + 3;
    }

    /* 
     * Pause the scrolling if they click the image.
     */
    function PreviewPause(e) {
      bPaused = !bPaused;
      tb.caption(bPaused ? 'Zoom (paused)':'Zoom');
      PreviewHover(e);
    }

    /*
     * Here we want to take the coordinates and grab a subsection of the ascii map, color it, and put it in the toolbar.
     */
    function PreviewHover(e, force) {
      // Some corrections for borders.
      var X; var Y;
      var span = document.getElementById('preview');
      var map = document.getElementById('previewmap');
      if ( !e ) e = window.event;
      if ( e && !force ) {
        X = TBGetX(e) - xOffset - 1;
        Y = TBGetY(e) - yOffset - 1;
      } else {
        X = document.LastX;
        Y = document.LastY;
        document.LastX = null;
        document.LastY = null;
      }
      // Make sure we're still on the picture.
      if ( X > ( map.width) || Y > ( map.height) ) return;
      if ( bPaused && !force ) return;
      // Position the rectangle if it exists.
      if ( pv ) {
	if ( _SARISSA_IS_IE ) pv.Y = (Y+2);
	else pv.Y = (Y-2);
        pv.X = (X-8);
        pv.style.top = pv.Y + 'px';
        pv.style.left = pv.X + 'px';
        pv.className = 'locate';
      }
      // If the mouse position changed, refresh the preview window.
      if ( span && ((X != document.LastX) || (Y != document.LastY)) ) {
        var o;
        var o = '';
        document.LastX = X; document.LastY = Y;
        for ( var i = Y - 10; i < Y + 10; i++) {
          if ( i > 0 ) {
            var line = sMapArr[i];
            // Colorize the resulting string, so it looks nice and pretty.  Use the map css codes from Ooga.
            if ( line ) {
		o += Colourize(line.substring(X-19, X+15)) + '<br>';
		o += AddAreas(X, i, Y - 10);
	    }
          }
        }
        span.innerHTML = o;
      }
    }

    /*
     * Returns the CSS id for a character.
     */
    function CSSID(s) {
      switch(s) {
        case '~':
        case 'R':
        case 'l':
        case 'r': return 'ri'; break;
        case 'w':
        case 'S': return 'sl'; break;
        case 'c':
        case '=':
        case '-':
        case '+':
        case '|':
        case '/':
        case '\\':
        case 'c':
        case '#': return 'pc'; break;
        case 'f':
        case 'v':
        case '.': return 'va'; break;
        case 'F': return 'ju'; break;
        case 'b':
        case ',':
        case 'z': return 'de'; break;
        case 'y': return 'x1'; break;
        case 't':
        case '!': return 'tu'; break;
        case 'h':
        case 'H':
        case '^': return 'mo'; break;
        case 's': return 'vo'; break;
        case '?': return 'sp'; break;
        case 'j': return 'ju'; break;
        case 'd': return 'de'; break;
        case 'C': return 'pc'; break;
        case 'w': return 'wa'; break;
        case 'i': return 'ri'; break;
        case 'x': return 'ba'; break;
        case 'V': return 'vo'; break;
        case 'L': return 'vo'; break;
        case '@': return 'vo'; break;
      }
      return 'unk';
    }

    /*
     * Add any area information to the HTML for the given coordinates.
     * Some hacks due to the frame of the toolbar class.
     */
    function AddAreas(X, Y, Top) {
        var mData = mAreas[Y];
	var o = '';
	if ( mData ) {
	    for( var i = 0; i < mData.length; i++ ) {
		var mArea = mData[i];
		if ( mArea &&  mArea[0] >= (X-19) && mArea[0] < (X+15) ) {
		    // Calculate the relative position.
		    // The frame the label is in includes the titlebar -- scale it and shift it down.
		    var top = (Y - Top + 1)/0.20;
                    top = parseInt(top);
		    top = top * 0.93 + 5;
		    // Calculate the left edge.
		    var left = ((34)-((X+15-mArea[0]))) / ((33)/100.0);
		    left = parseInt(left);
		    left = left * 0.93 + 3;
		    // And add the div section.
		    if ( top < 98 )
			o += '<div class="label" style="top: ' + top + '%; left: ' + left + '%;">' + mArea[1] + '</div>';
		}
	    }
        }
	return o;
    }

    /*
     * Insert CSS codes to color the map section.
     */
    function Colourize(line) {
      var sOld = null;
      var o = '';
      for ( var i = 0; i < line.length; i++) {
        var sNew = line.substring(i,i+1);
        var sNewCCS = CSSID(sNew);
        if ( sOld != sNewCCS ) {
          sOld = sNewCCS;
          if ( sOld ) o += '</span>';
          o += '<span class="' + sNewCCS + '">' + sNew;
        } else o += sNew;
      }
      o += '</span>';
      return o;
    }

    function AreaSort(a, b) {
	if ( a[3] < b[3] ) return -1;
	if ( a[3] > b[3] ) return 1;
	return 0;
    }

    /*
     * Takes the areas list and populates our area list data array.
     */
    function PreviewParse() {
	var sParse = sAreas.split('\n');
	var o = '<select id="areanames" size="15">\n';
	var areas = document.getElementById('arealist');
	var areadata = [];
	var get = _GET();
	for ( var i = 0; i < sParse.length; i++) {
		var sLine = sParse[i];
		var sData = sLine.split(':');
		if ( sData[0] == sContinent ) {
			if ( !mAreas[sData[1]] ) mAreas[sData[1]] = Array( Array(sData[2], sData[3]) );
			else mAreas[sData[1]] = mAreas[sData[1]].concat( Array( Array( sData[2], sData[3] ) ));
			if ( areas) areadata = areadata.concat( Array(sData) );
		}
	}
	if ( areas ) {
		areadata.sort(AreaSort);
		for ( var i = 0; i < areadata.length; i++ ) {
			sData = areadata[i];
			o = o + '<option id="' + sData[2] + ',' + sData[1] + '"' +
				(get['x'] == sData[2] && get['y'] == sData[1] ? ' SELECTED':'') +
				'>' + sData[3] + '</option><br>\n';
		}
		areas.innerHTML = o;
	}
    }


