/*global $ */
// * pixel offsets all over the place
// * via cleanup
// * popup dialogs
// * scales
/*extern $, console */
// the map data structure - updated via JSON from the server
var map = {
valid: 0
};
var mapfile = '';
var lastserial = 0;
var dragstate = {
linkmdown: false,
dragmdown: false,
addedVia: false,
dragstart: {
x: -1,
y: -1
},
dragstop: {
x: -1,
y: -1
},
dragitem: '',
dragoffset: {
x: 0,
y: 0
}
};
var interactmode = '';
function getMousePosition(event)
{
var x, y;
x = event.pageX || (event.clientX
+ (document.documentElement.scrollLeft || document.body.scrollLeft)) || 0;
y = event.pageY || (event.clientY
+ (document.documentElement.scrollTop || document.body.scrollTop)) || 0;
return {
x: x,
y: y
};
}
var WMEditor = {
map: {
valid: 0
}, // the downloaded JSON data
mapfile: '', // which file we're working with
lastserial: 0, // last serial number for data synchronisation
node1: '', // selected node for link creation
node2: '', // second node for link creation
act_node_add: function() { },
act_node_add_click: function() { },
act_link_add: function() { },
act_link_add_click1: function() { },
act_link_add_click2: function() { },
syncnodes: function()
{
var node, nodeid, existing, origin_x, origin_y, newx, newy;
origin_x = parseInt(jQuery('#existingdata').css('left'), 10);
origin_y = parseInt(jQuery('#existingdata').css('top'), 10);
// Destroy dead nodes as appropriate
jQuery('img.mapnode').each(function(i)
{
var myname = jQuery(this).attr('id');
myname = myname.replace(/^mapnode_/, '');
if (map.nodes[myname]) {
// it still exists, keep it around
}
else {
jQuery(this).remove();
}
});
// now go through the list and move around or add new ones...
for (node in WMEditor.map.nodes) {
if (WMEditor.map.nodes[node].name !== 'DEFAULT') {
nodeid = 'mapnode_' + WMEditor.map.nodes[node].name;
existing = jQuery('img#' + nodeid);
if (existing.size() === 0) {
jQuery('#nodecontainer').append(
'');
existing = jQuery('img#' + nodeid);
}
// one way or another, by here we have a node, I hope.
newx = origin_x + WMEditor.map.nodes[node].x;
newy = origin_y + WMEditor.map.nodes[node].y;
existing.css({
position: 'absolute',
left: newx + "px",
top: newy + "px",
'z-index': 30
});
}
}
},
syncvias: function()
{
var link, vs, newx, newy, origin_x, origin_y, existing, via_id, i;
// something here needs to clear existing VIAs
origin_x = parseInt(jQuery('#existingdata').css('left'), 10);
origin_y = parseInt(jQuery('#existingdata').css('top'), 10);
jQuery('.deadvia').remove();
for (link in WMEditor.map.links) {
if (WMEditor.map.links[link].name !== 'DEFAULT') {
console.log("LINK " + link);
if (WMEditor.map.links[link].via.length > 0) {
console.log(link + ' has VIAs');
vs = WMEditor.map.links[link].via;
for (i = 0; i < vs.length; i += 1) {
console.log('VIA ' + vs[i][0] + ',' + vs[i][1]);
via_id = 'mapvia_' + link + '_via_' + i;
existing = jQuery('img#' + via_id);
if (existing.size() === 0) {
jQuery('#nodecontainer').append(
'
');
existing = jQuery('img#' + via_id);
}
newx = origin_x + vs[i][0] - 5;
newy = origin_y + vs[i][1] - 5;
existing.css({
position: 'absolute',
left: newx + "px",
top: newy + "px",
'z-index': 30
});
console.log("created " + via_id + ' at ' + newx + ',' + newy);
}
}
}
}
},
// Synchronise the JSON data with the DOM representation
syncmap: function()
{
// only do anything if the data is valid
jQuery('#busy').show();
if (WMEditor.map.valid === 1) {
WMEditor.syncnodes();
WMEditor.syncvias();
}
jQuery('#busy').hide();
},
// Fetch the JSON data from the server for this map
loadmap: function()
{
console.log('Fetching JSON.');
$.getJSON("editor-backend.php", {
map: WMEditor.mapfile,
"cmd": "dump_map",
"serial": WMEditor.lastserial
}, function(json)
{
console.log('Inside JSON function');
if (json.valid === 1) {
WMEditor.map = json;
console.log('Fetching bg image data.');
jQuery('#existingdata').attr('src', json.map.mapcache + "?s=" + json.serial);
WMEditor.lastserial = json.serial;
// jQuery('#existingdata').attr('src',json.map.mapcache);
$.get('editor-backend.php', {
map: WMEditor.mapfile,
cmd: "imagemap"
}, function(cont)
{
jQuery('map#weathermap_imap').empty();
// jQuery('map#weathermap_imap').html(cont);
// Getting medieval here - jQuery doesn't seem to be interested in Imagemaps??
var oldskool = document.getElementById('weathermap_imap');
oldskool.innerHTML = cont;
reapplyLinkEvents();
});
console.log('about to syncmap()');
WMEditor.syncmap();
} else {
console.log('Failed to get good JSON');
alert('Got invalid JSON map data');
}
console.log('Leaving JSON function');
});
console.log('Done with map_refresh()');
},
// force a refresh of the map
refresh: function()
{
WMEditor.loadmap();
WMEditor.syncmap();
}
};
function reapplyLinkEvents()
{
// unbind, then re-apply all events for links.
// is this actually necessary?
jQuery('area[@id^=LINK:]').unbind();
jQuery('area[@id^=LINK:]').mousedown(function(ev)
{
var pos;
console.log('LINK mousedown');
dragstate.linkmdown = true;
// retrieve positioning properties
pos = getMousePosition(ev);
dragstate.dragstart.x = pos.x;
dragstate.dragstart.y = pos.y;
dragstate.dragitem = jQuery(this).attr('id');
return(false);
});
jQuery('area[@id^=LINK:]').mousemove(function()
{
if (dragstate.linkmdown) {
return(false);
}
return(true);
});
jQuery('area[@id^=LINK:]').mouseup(function(ev)
{
var pos, dx, dy;
// verify if we've moved much since the down - if we did, it's not a click
pos = getMousePosition(ev);
dragstate.dragstop.x = pos.x;
dragstate.dragstop.y = pos.y;
dx = Math.abs(dragstate.dragstop.x - dragstate.dragstart.x);
dy = Math.abs(dragstate.dragstop.y - dragstate.dragstart.y);
if ((dx + dy) < 4) {
// treat this is a click - we're still inside the link, and we didn't move far
alert('click on ' + dragstate.dragitem);
} else {
dragstate.dragitem = '';
dragstate.dragstart = {
x: -1,
y: -1
};
dragstate.dragstop = {
x: -1,
y: -1
};
if (dragstate.addedVia) {
jQuery('#newvia').remove();
dragstate.addedVia = false;
}
}
console.log('LINK mouseup');
dragstate.linkmdown = false;
});
}
function reapplyDraggableEvents()
{
var origin_x, origin_y;
jQuery('.draggable').unbind();
jQuery('.draggable').mousedown(function(ev)
{
var pos, w, h, t, l;
dragstate.dragmdown = true;
console.log('mousedown');
pos = getMousePosition(ev);
dragstate.dragstart.x = pos.x;
dragstate.dragstart.y = pos.y;
dragstate.dragitem = jQuery(this).attr('id');
w = jQuery(this).width();
h = jQuery(this).height();
t = parseInt(jQuery(this).css('top'), 10);
l = parseInt(jQuery(this).css('left'), 10);
dragstate.dragoffset.x = -(w / 2);
dragstate.dragoffset.y = -(h / 2);
return(false);
});
jQuery('.draggable').mousemove(function(ev) { });
jQuery('.draggable').mouseup(function(ev)
{
var pos, dx, dy;
console.log('mouseup');
dragstate.dragmdown = false;
// verify if we've moved much since the down - if we did, it's not a click
pos = getMousePosition(ev);
dragstate.dragstop.x = pos.x;
dragstate.dragstop.y = pos.y;
dx = Math.abs(dragstate.dragstop.x - dragstate.dragstart.x);
dy = Math.abs(dragstate.dragstop.y - dragstate.dragstart.y);
if ((dx + dy) < 4) {
// treat this is a click - we're still inside the link, and we didn't move far
alert('click on ' + dragstate.dragitem);
} else {
origin_x = parseInt(jQuery('#existingdata').css('left'), 10);
origin_y = parseInt(jQuery('#existingdata').css('top'), 10);
if (dragstate.dragitem.slice(0, 8) === 'mapnode_') {
dragstate.dragitem = dragstate.dragitem.slice(8,
dragstate.dragitem.length);
$.getJSON('editor-backend.php', {
map: mapfile,
cmd: "move_node",
x: (pos.x - origin_x),
y: (pos.y - origin_y),
nodename: dragstate.dragitem
}, function() { map_refresh(); });
}
if (dragstate.dragitem.slice(0, 7) === 'mapvia_') {
dragstate.dragitem = dragstate.dragitem.slice(7,
dragstate.dragitem.length);
$.getJSON('editor-backend.php', {
map: mapfile,
cmd: "move_via",
x: (pos.x - origin_x),
y: (pos.y - origin_y),
vianame: dragstate.dragitem
}, function() { map_refresh(); });
}
dragstate.dragitem = '';
dragstate.dragstart = {
x: -1,
y: -1
};
dragstate.dragstop = {
x: -1,
y: -1
};
dragstate.addedVia = false;
}
return(false);
});
}
function syncmap()
{
var i, existing, newx, newy, node, link, origin_x, origin_y, nodeid, via_id, vs;
jQuery('#busy').show();
// first, clear out the NODES that have disappeared...
if (1 === 0) {
// this doesn't flicker as much as you might expect
jQuery('img.mapnode').remove();
} else {
// this just seems to die for some reason.
jQuery('img.mapnode').each(function(i)
{
var myname = jQuery(this).attr('id');
myname = myname.replace('mapnode_', '');
// alert(myname);
if (map.nodes[myname])
//if(1==0)
{
// it still exists, keep it around
}
else {
jQuery(this).remove();
}
});
}
origin_x = parseInt(jQuery('#existingdata').css('left'), 10);
origin_y = parseInt(jQuery('#existingdata').css('top'), 10);
// now go through the list and move around or add...
for (node in map.nodes) {
if (map.nodes[node].name !== 'DEFAULT') {
nodeid = 'mapnode_' + map.nodes[node].name;
existing = jQuery('img#' + nodeid);
if (existing.size() !== 0) {
//alert('The node already exists called ' + nodeid);
}
else {
jQuery('#nodecontainer').append(
'');
existing = jQuery('img#' + nodeid);
}
// one way or another, by here we have a node, I hope.
newx = origin_x + map.nodes[node].x;
newy = origin_y + map.nodes[node].y;
existing.css({
position: 'absolute',
left: newx + "px",
top: newy + "px",
'z-index': 30
});
}
}
// something here needs to clear existing VIAs
jQuery('.deadvia').remove();
for (link in map.links) {
if (map.links[link].name !== 'DEFAULT') {
console.log("LINK " + link);
if (map.links[link].via.length > 0) {
console.log(link + ' has VIAs');
vs = map.links[link].via;
for (i = 0; i < vs.length; i += 1) {
console.log('VIA ' + vs[i][0] + ',' + vs[i][1]);
via_id = 'mapvia_' + link + '_via_' + i;
existing = jQuery('img#' + via_id);
if (existing.size() !== 0) { }
else {
jQuery('#nodecontainer').append(
'
');
existing = jQuery('img#' + via_id);
}
newx = origin_x + vs[i][0] - 5;
newy = origin_y + vs[i][1] - 5;
existing.css({
position: 'absolute',
left: newx + "px",
top: newy + "px",
'z-index': 30
});
console.log("created " + via_id + ' at ' + newx + ',' + newy);
}
}
}
}
reapplyDraggableEvents();
jQuery('#busy').hide();
}
function map_refresh()
{
console.log('Fetching JSON.');
$.getJSON("editor-backend.php", {
map: mapfile,
"cmd": "dump_map",
"serial": lastserial
}, function(json)
{
console.log('Inside JSON function');
if (parseInt(json.valid, 10) === 1) {
map = json;
console.log('Fetching bg image data.');
jQuery('#existingdata').attr('src', json.map.mapcache + "?s=" + json.serial);
lastserial = json.serial;
// jQuery('#existingdata').attr('src',json.map.mapcache);
$.get('editor-backend.php', {
map: mapfile,
cmd: "imagemap"
}, function(cont)
{
jQuery('map#weathermap_imap').empty();
// jQuery('map#weathermap_imap').html(cont);
// Getting medieval here - jQuery doesn't seem to be interested in Imagemaps??
var oldskool = document.getElementById('weathermap_imap');
oldskool.innerHTML = cont;
reapplyLinkEvents();
});
console.log('about to syncmap()');
syncmap();
} else {
console.log('Failed to get good JSON');
alert('Got invalid JSON map data');
}
console.log('Leaving JSON function');
});
console.log('Done with map_refresh()');
}
function openmap(mapname)
{
console.log('Opening map: ' + mapname);
WMEditor.mapfile = mapname;
mapfile = mapname;
jQuery('#welcome').hide();
jQuery('#filepicker').hide();
jQuery('#toolbar').show();
jQuery('#themap').show();
jQuery('#busy').hide();
jQuery('img.mapnode').remove();
jQuery('img.mapvia').remove();
jQuery('#filename').html(mapname);
console.log('Refreshing map: ' + mapname);
map_refresh();
// WMEditor.loadmap();
}
function showpicker()
{
jQuery('#welcome').hide();
jQuery('#filepicker').show();
jQuery('#toolbar').hide();
jQuery('#themap').hide();
jQuery('#busy').show();
jQuery('#filelist').empty();
jQuery('#filelist').append(
'
Fetching File List...
';
}
jQuery('#filelist').append('
');
theItem = jQuery('#newvia');
dragstate.dragoffset.x = -theItem.width() / 2;
dragstate.dragoffset.y = -theItem.height() / 2;
dragstate.addedVia = true;
}
}
x = pos.x + dragstate.dragoffset.x;
y = pos.y + dragstate.dragoffset.y;
theItem.css({
left: x,
top: y
});
}
});
jQuery('#btn_refresh').click(function() { map_refresh(); });
jQuery('#btn_selectfile').click(function() { showpicker(); });
jQuery('#btn_addnode').click(function() { nodeadd(); });
jQuery('#btn_addlink').click(function() { linkadd(); });
reapplyDraggableEvents();
reapplyLinkEvents();
});