
if (typeof caliper == 'undefined')
    var caliper = {};

if ( typeof caliper.map == "undefined" ) 
    caliper.map = {};   
    
if (typeof caliper.map.handler == "undefined" ) 
    caliper.map.handler = {};   

//Title and balloon help for map window and map toolbox
caliper.map.mapWindowTitle   = "Map";
caliper.map.mapWindowBalloon = "To navigate this map, choose one of the zoom or pan tools and click on the map window.";
caliper.map.toolTitle        = "Navigate the Map";
caliper.map.toolBalloon      = "To change the map location, choose one of the zoom or pan tools and click and drag the cursor on the map. "+
                               "To get information about the layers under the cursor, choose the (i) info button and then click on the map.";
    
caliper.Annotation = null;

caliper.map.SNAP_DISTANCE = 10;    //10 pixels
caliper.map.MAX_MAP_HISTORY = 20;  //maximum of previous maps stored in history
caliper.map.MAPWINDOWINITX = 262;  //x position of map window
caliper.map.IMAGEWIDTH = 650;      //default map image width (in pixels)
caliper.map.IMAGEHEIGHT = 650;     //default map image height (in pixels)

caliper.map.MapURL = ""; 
caliper.map.MapLegendURL = ""; 
caliper.map.MapScope = ""; 
caliper.map.MapScale = 10;
caliper.map.ImageWidth = 0;  
caliper.map.ImageHeight = 0;  

caliper.map.zoomLevels = new Array(2500, 5000, 10000,20000,50000,100000, 200000, 500000, 1000000);
caliper.map.zoomTargetScale = 10;

caliper.map.mapSizes = new Array(200,300,350,500,650);

caliper.map.GisdkTempFileFolder = "/TempMapFiles/" 

caliper.map.command = 'zmin';

caliper.map.mapCenter = {x: 0, y: 0};

caliper.map.mapContainer = null; //container object on which the surface object and image object display
caliper.map.mapSurface = null;   //surface object to attach map image

caliper.map.shapeRect = null;    //rectangle scope defined by zoom and select tools, in the format of top_left_x | top_left_y | width | height
caliper.map.shapePan  = null;    //pan-shifting values, in the format of shift_x|shift_y
caliper.map.shapeCircle = null;  //circle specs create by select_circle tool, in the format of center_x | center_y | radius_x | radius_y

caliper.map.shapeToolContainer = null; //library of shape tools and methods: rect, circle, mark and laso
caliper.map.mouseUpHandler = null;     //handler function associated with individual tool, gets called on mouse-up event on map image object

caliper.map.updateMapCallbackMessages = null; //a list of call-back messages set by the caller of MSG_updateMap, they will be fired onup
                                              //successfully finished onCompleteUpdateMap

caliper.map.mapScopeHistory = [];  //stores the map scopes in chronical order

caliper.map.closeLasso = true;
caliper.map.circleSelected = false;

caliper.map.click_orig_x = 0;
caliper.map.click_orig_y = 0;
caliper.map.mouse_down_clicked = false;

caliper.map.print_window = null;

caliper.map.bookmarks = null;
caliper.map.legendVisible = true;


caliper.initMapForm = function () {
    //set map window and toolbox title and balloon help
    jQuery("#map_name").html(caliper.map.mapWindowTitle);
    jQuery("#mapWindowBar").attr("title", caliper.map.mapWindowBalloon);
    jQuery("#mapToolTitle").html(caliper.map.toolTitle);
    jQuery("#mapToolBar").attr("title", caliper.map.toolBalloon);
    

    // preload toolbox button images
    jQuery('#mapToolBox .gisdk_buttons').each( function() { 
        var pimg = jQuery(this).attr("preload");
        var pstatus = jQuery(this).attr("gisdk_status");

        if (pimg && pimg.length > 5) jQuery(this).attr("src", pimg);
        if (pstatus && pstatus.length > 5) jQuery(this).attr("title", pstatus);
        });      

    //adjust map frame width
    jQuery("#mapWindow").css("width", caliper.map.ImageWidth + 5);
    
    //hide guiding image
    jQuery("#gisdk_map_image").css("visibility","hidden");
    jQuery("#gisdk_map_image").attr("height",1);
    jQuery("#gisdk_map_image").attr("width",1);
    
    //make map window draggable
    //jQuery("#mapWindow").draggable({handle:'.title_bar', start: caliper.map.startMapDragging, stop:caliper.map.adjustZoomBarPosition});

    //make toolbox draggable
    //jQuery("#mapToolBox").draggable({handle:'.title_bar', start: caliper.map.startToolboxDragging, stop:caliper.map.checkToolboxDocking});

    //make legend box draggable
    //jQuery("#legendWindow").draggable({handle:'.title_bar'});

    //jQuery("#zoomBar").slider({slide:caliper.map.onZoomBarMove, start: caliper.map.onZoomBarStart, stop:caliper.map.onZoomBarEnd});        
    
    //subscribe to listen to event messages
    jQuery("#mapWindow").bind("MSG_updateMap",  caliper.map.handler.redrawMap);
    jQuery("#mapWindow").bind("MSG_clearTools",  caliper.map.clearTools);
    jQuery("#mapWindow").bind("MSG_completeSelectingMap",  caliper.map.handler.closePrintWindow);

    //jQuery('#zoomMinus').click( caliper.map.zoomMinus);
    //jQuery('#zoomPlus').click( caliper.map.zoomPlus);

    //get pre-defined quick-zoom levels and map size steps
    caliper.mapService.LoadConfig( "MapControl.config", null, caliper.map.handler.onCompleteMapSettings);   
    updateIcons();
    
    CCUtil.dockToolbox("MapControl");
    
    //set default tool to zoomin
    caliper.map.clickButtonZoomin();
    };


caliper.map.getZoomValue = function(evt) {
    var CARRIAGE_RETURN = 13; //key code for carriage return
    var BACK_SPACE = 8; //key code for back-space
    var ALEFT=37, AUP=38, ARIGHT=39,ADOWN=40;
    var validKeys = [CARRIAGE_RETURN, BACK_SPACE, ALEFT, AUP,ARIGHT, ADOWN];
     
    var hitReturn = false;
    var zoomValue, zoomValueInt = -1;
    var keyCode = -1;

    zoomValue = jQuery("#zoomValue").attr("value");

    if (dojo.isIE) keyCode = window.event.keyCode;
    else keyCode = evt.keyCode;
    
    if (validKeys.indexOf(keyCode) < 0 && (keyCode < 48 || keyCode > 57)) {
        jQuery("#zoomValue").attr("value",zoomValue.substring(0, zoomValue.length -1));
        return; //must be between 0-9
        }
    if (keyCode == CARRIAGE_RETURN) hitReturn = true; 

    if (hitReturn) {
        var segments = zoomValue.split(":");
        if (segments.length > 1) zoomValue = segments[segments.length-1];
        zoomValueInt = parseInt(zoomValue);
        
        if (typeof(zoomValueInt) != "NaN" && zoomValueInt > 0) {
            
            caliper.map.zoomTargetScale = zoomValueInt;
            caliper.map.onZoomBarEnd(evt);            
            }
        }
    };

    caliper.map.adjustZoomBarPosition = function() {
        var zoomBar = jQuery("#zoomBar");
        var height_shift = 40;
        return;
        
        if (zoomBar[0]) {
            var map_left = parseInt(jQuery("#mapWindow").css("left"));
            var map_top = parseInt(jQuery("#mapWindow").css("top"));

            jQuery("#zoomBar").css("left", map_left + 10);
            jQuery("#zoomBar").css("top", map_top + caliper.map.ImageHeight + height_shift);
            jQuery("#zoomMinus").css("left", map_left + 5);
            jQuery("#zoomMinus").css("top", map_top + caliper.map.ImageHeight + height_shift + 13);
            jQuery("#zoomPlus").css("left", map_left + 220);
            jQuery("#zoomPlus").css("top", map_top + caliper.map.ImageHeight + height_shift + 13);
            jQuery("#zoomValuePrefix").css("left", map_left + 238);
            jQuery("#zoomValuePrefix").css("top", map_top + caliper.map.ImageHeight + height_shift + 15);
            jQuery("#zoomValue").css("left", map_left + 248);
            jQuery("#zoomValue").css("top", map_top + caliper.map.ImageHeight + height_shift + 12);
        }

        if (typeof (caliper.map.zoomLevels) != "object") jQuery("#zoomBar").slider("disable");
        caliper.map.zoomLevels.sort(function(a, b) { return a - b });
    };
    
caliper.map.setCommand = function (input_command) {
    caliper.map.command = input_command;
    };
  
/**
* Mouse_Down event handler: record mouse coordinate, create drawing object.
*/
caliper.map.onMouseDown = function(event) {
    
    console.log("caliper.map.onMouseDown " + caliper.map.command);
    
    var current_command = caliper.map.command;
    if (!current_command) return;

    caliper.map.mouse_down_clicked = true;

    if (dojo.isIE)
        {
        caliper.map.click_orig_x = event.x; 
        caliper.map.click_orig_y = event.y; 
        }
    else
        {
        caliper.map.click_orig_x = event.layerX; 
        caliper.map.click_orig_y = event.layerY; 

        if (CCUtil.isFF35 && typeof(event.target.offsetTop) != 'undefined')
            caliper.map.click_orig_y = caliper.map.click_orig_y - event.target.offsetTop;
        }

    switch (current_command) 
        {
        case 'select_rect':
        case 'zmin':
        case 'zmout':
            if (caliper.map.shapeToolContainer)
                caliper.map.shapeToolContainer.createRect({x:caliper.map.click_orig_x, y:caliper.map.click_orig_y, rect_shreshold: 2});

            break;
        case 'pan':

            break;
        
        case 'info':
            if (caliper.map.shapeToolContainer) {
                if (caliper.map.shapeToolContainer.existsMark())
                    caliper.map.shapeToolContainer.mark.update({x:caliper.map.click_orig_x, y:caliper.map.click_orig_y});
                else
                    caliper.map.shapeToolContainer.createMark({x:caliper.map.click_orig_x, y:caliper.map.click_orig_y});
                }
            break;
        case 'select_point':
            if (caliper.map.shapeToolContainer) {
                caliper.map.clearTools();
                caliper.map.shapeToolContainer.createMark({x:caliper.map.click_orig_x, y:caliper.map.click_orig_y});
                }
            break;
        case 'select_circle':       
            if (caliper.map.shapeToolContainer) {
                if (caliper.map.shapeToolContainer.circle)
                    caliper.map.shapeToolContainer.circle.destroy();
                    
                caliper.map.shapeToolContainer.createCircle({x:caliper.map.click_orig_x, y:caliper.map.click_orig_y});
                }
            break;
        case 'move_circle':     
            if (caliper.map.shapeToolContainer && caliper.map.shapeToolContainer.circle)
                caliper.map.circleSelected = caliper.map.shapeToolContainer.circle.select({x:caliper.map.click_orig_x, y:caliper.map.click_orig_y, method:'inside'});
            break;
            
        case 'select_lasso':
        case 'distance':
            var lasso_length=0;
            
            if (caliper.map.shapeToolContainer) {
                if (caliper.map.shapeToolContainer.lasso) {
                    caliper.map.shapeToolContainer.lasso.destroy();
                    caliper.map.shapeToolContainer.createLasso({x:caliper.map.click_orig_x, y:caliper.map.click_orig_y});
                    }
                else if (caliper.map.shapeToolContainer.lassoSegments) {
                    lasso_length = caliper.map.shapeToolContainer.lassoSegments.addNode({x:caliper.map.click_orig_x, y:caliper.map.click_orig_y});
                    var arguments = {distance_pixel: lasso_length};
                    jQuery("div.listener").trigger("MSG_updateDistance",new Array(arguments));  
                    }
                else
                    caliper.map.shapeToolContainer.createLasso({x:caliper.map.click_orig_x, y:caliper.map.click_orig_y});
                }

            break;
        } //switch current_command


    dojo.stopEvent(event);

    };

/**
* Mouse_DoubleClick event handler -  gets called in addition to onMouseDown
* double click to close selecting lasso or measuring tool
*/
caliper.map.onDoubleClick = function(event) {
    if (!caliper.map.mouse_down_clicked) return;

    if((caliper.map.command == 'select_lasso' || caliper.map.command == 'distance' ) && caliper.map.shapeToolContainer.lassoSegments)
        {
        var arg = {};
        if (caliper.map.command == 'select_lasso' )  arg.autoClose = true;
        else arg.autoClose = false;
        
        caliper.map.shapeToolContainer.completeLasso(caliper.map.shapeToolContainer.lassoSegments, arg);
        
        caliper.map.mouse_down_clicked = false;

        var measuringString = caliper.map.shapeToolContainer.generateSelectingString();
        var segments = measuringString.split("|");
        
        if (caliper.map.command == "distance" && segments.length > 6) {
            //X1 = Xn & Y1 = Yn: shape is closed, do Area calculation
            if (segments[0] == segments[segments.length -2] && segments[1] == segments[segments.length -1] ) {
                var request = {};

                request.LassoPoints = measuringString;
                request.Command = caliper.map.command;
                request.ImageWidth = caliper.map.ImageWidth;
                request.ImageHeight = caliper.map.ImageHeight;
                request.MapScope = caliper.map.MapScope;
                request.MapFile = CCUtil.getGisdkProperties("MapFile"); 
                caliper.mapService.DoMethod("MapService.MeasureDistanceAndArea", request, "MapControl.config" , "MapControl" , caliper.map.onCompleteMeasuring);
                }
            }
        }
    dojo.stopEvent(event);
    };


/**
* Mouse_Move event handler: update drawing object.
*/
caliper.map.onMouseMove = function(event) {
    if (!caliper.map.mouse_down_clicked) return;
    
    if (dojo.isIE)
        {
        current_x = event.x; 
        current_y = event.y; 
        }
    else
        {
        current_x = event.layerX; 
        current_y = event.layerY; 

        if (CCUtil.isFF35 && typeof(event.target.offsetTop) != 'undefined')
            current_y = current_y - event.target.offsetTop;
        }

    if (current_x < 0) current_x = 0;
    else if (current_x > caliper.map.ImageWidth - 1) current_x = caliper.map.ImageWidth-1;
    if (current_y < 0) current_y = 0;
    else if (current_y > caliper.map.ImageHeight-1) current_y = caliper.map.ImageHeight-1;


    if(caliper.map.mouse_down_clicked)
        {

        rect_orig_x    = caliper.map.click_orig_x;
        rect_orig_y    = caliper.map.click_orig_y;
        
        switch (caliper.map.command) 
            {
            
            case 'select_rect':
            case "zmin":
            case "zmout":
                if (caliper.map.shapeToolContainer && caliper.map.shapeToolContainer.rect)
                    caliper.map.shapeToolContainer.rect.update({x:current_x, y:current_y });
                break;
                
            case 'pan':
                if ( current_x > caliper.map.ImageWidth)
                    current_x = caliper.map.ImageWidth;
                else if ( current_x < 0) 
                    current_x = 0;
                    
                if ( current_y > caliper.map.ImageHeight)
                    current_y = caliper.map.ImageHeight;
                else if (current_y < 0)
                    current_y = 0;
                        
                if (map_image_obj)
                    map_image_obj.setTransform(dojox.gfx.matrix.translate(current_x-caliper.map.click_orig_x, current_y-caliper.map.click_orig_y)); //clickw,clickh));
                break;      //PAN
            case 'select_circle':
                r1 = Math.floor(Math.sqrt((current_x-caliper.map.click_orig_x) * (current_x-caliper.map.click_orig_x) + (current_y-caliper.map.click_orig_y) * (current_y-caliper.map.click_orig_y)));
   
                if (caliper.map.shapeToolContainer && caliper.map.shapeToolContainer.circle) {
                    r1 = caliper.map.shapeToolContainer.circle.update({r:r1});
                    var arguments = {distance_pixel: r1};
                    jQuery("div.listener").trigger("MSG_updateDistance",new Array(arguments));  
                    }
                break;
            case 'move_circle':     
                if (caliper.map.shapeToolContainer && caliper.map.shapeToolContainer.circle && caliper.map.circleSelected)
                    caliper.map.shapeToolContainer.circle.move({dx:current_x-caliper.map.click_orig_x, dy:current_y-caliper.map.click_orig_y});
                break;
            case 'select_lasso':
            case 'distance':
                if (caliper.map.shapeToolContainer.lassoSegments) 
                    caliper.map.shapeToolContainer.lassoSegments.update({x:current_x, y:current_y});
                break;
            } //switch caliper.map.command

        } //if(caliper.map.mouse_down_clicked)

    dojo.stopEvent(event);
    };

//
//image coordinate values of mouse clicks that get set to hidden variables:
// zmin/zmout/info/select_by_rect/select_by_point:
//  caliper.map.shapeRect  -  string in the format of top_left_x | top_left_y | width | height
//
// pan:
//  caliper.map.shapePan   -  string in the format of shift_x | shift_y 
//
// circle:
//  caliper.map.shapeCircle-  String in the format of center_x | center_y | radius_x | radius_y
//
/**
* Mouse_Up event handler: generate drawing object shape, destroy drawing object, and send
* command and shape coordinates to web service.
*/
caliper.map.onMouseUp= function(event)
{
    
    console.log("caliper.map.onMouseUp " + caliper.map.command);
    
    var current_command = caliper.map.command;

    switch (current_command) 
        {
        case 'select_rect':
        case 'select_move_rect':
            break;
            
        case 'zmin':
        case 'zmout':
            if (caliper.map.shapeToolContainer && caliper.map.shapeToolContainer.rect) {
                caliper.map.shapeRect = caliper.map.shapeToolContainer.rect.toString();  //rectangle shape specification in the format of UL_x|UL_y|width|height
                caliper.map.shapeToolContainer.rect.destroy();
                }
            
            break;
        case 'pan':     
            var transform = map_image_obj.getTransform();
            var shift_x = 0, shift_y = 0;
            
            if (transform) {
                shift_x = transform.dx;
                shift_y = transform.dy;
                }
            
            if (shift_x == 0 && shift_y == 0) {
                shift_x = caliper.map.mapCenter.x - caliper.map.click_orig_x;
                shift_y = caliper.map.mapCenter.y - caliper.map.click_orig_y;
                }
                
            caliper.map.shapePan = shift_x+"|"+shift_y;    //x_shift|y_shift

            break;

        
        case 'info':
            if (caliper.map.shapeToolContainer.existsMark())
                caliper.map.shapeRect = caliper.map.shapeToolContainer.mark.toString() + "|0|0" ;

            break;
        case 'select_point':
            if (caliper.map.shapeToolContainer.existsMark()) {
                caliper.map.shapeRect = caliper.map.shapeToolContainer.mark.complete();
                caliper.map.shapeRect = caliper.map.shapeToolContainer.addMark(caliper.map.shapeRect = caliper.map.shapeToolContainer.mark);
                caliper.map.shapeRect = caliper.map.shapeToolContainer.mark.toString() + "|0|0" ;
                }
                
            caliper.select.onClickSelectApply("Add");
            break;
        case 'select_circle':
        case 'move_circle':     
            if (caliper.map.shapeToolContainer && caliper.map.shapeToolContainer.circle) {
                caliper.map.shapeToolContainer.circle.complete();
                caliper.map.shapeCircle = caliper.map.shapeToolContainer.circle.toString();
                }
            caliper.map.circleSelected = false;
            
            break;

        } //switch (current_command)
        
    if (current_command != 'select_lasso' && current_command != 'distance')
        caliper.map.mouse_down_clicked = false;
    dojo.stopEvent(event);

    if (current_command != 'dummy')
        {
   
        if (caliper.map.mouseUpHandler)
            eval(caliper.map.mouseUpHandler);    
        }
    return false;

};

caliper.map.adjustZoomBarLevel = function() {
    var i;
    return;
    
    if (caliper.map.MapScale >= caliper.map.zoomLevels[caliper.map.zoomLevels.length - 1]) jQuery("#zoomBar").slider("moveTo", 0);
    else {
        for (i = 0; i < caliper.map.zoomLevels.length; i++) {
            if (caliper.map.MapScale <= caliper.map.zoomLevels[i]) {
                jQuery("#zoomBar").slider("value", 100 - parseInt(i / caliper.map.zoomLevels.length * 100));
                break;
            }
        }

    }

    jQuery("#zoomValue").attr("value", caliper.map.MapScale);
};
    
caliper.map.onZoomBarStart = function(event) {
    caliper.map.zoomTargetScale = caliper.map.MapScale;
    };
    

caliper.map.onZoomBarMove = function(event, ui) {
    var i, position;
    var slideValue = 101 - jQuery("#zoomBar").slider("value");  
    var current_x, current_y;
    
    if (!event && !ui) return;
    
    //current_x = event.clientX; 
    //current_y = event.clientY; 

    position = parseInt(slideValue / 100 * caliper.map.zoomLevels.length);
    if (position >= caliper.map.zoomLevels.length) 
        caliper.map.zoomTargetScale = caliper.map.zoomLevels[caliper.map.zoomLevels.length -1];
    else caliper.map.zoomTargetScale = caliper.map.zoomLevels[position];
    
    jQuery("#zoomValue").attr("value",caliper.map.zoomTargetScale);
    };
    
caliper.map.onZoomBarEnd = function(event, ui) {
    var args = [];
    var slideValue = 101 - jQuery("#zoomBar").slider("value");  
    var position, scale;
    var bZoomStepClicked = false;
    
    try {
        var eventSrcID = event.originalEvent.srcElement.id;
        bZoomStepClicked = (eventSrcID == "zoomMinus" || eventSrcID == "zoomPlus") ? true : false;
    }
    catch (ex) {}    
        
    if (event != null && ((event.originalEvent && event.originalEvent.type == "mouseup") || (event.type && event.type == "keyup") || bZoomStepClicked)) {
//         || ui != null) {
        args.Command = "redraw";
        if (event && event.originalEvent && event.originalEvent.type == "mouseup" ) 
            args.Command = "redraw_zoombar";
        else if (ui && ui.value != null) {
            position = parseInt((slideValue+1) / 100 * caliper.map.zoomLevels.length);
            if (position >= caliper.map.zoomLevels.length) 
                scale = caliper.map.zoomLevels[caliper.map.zoomLevels.length -1];
            else scale = caliper.map.zoomLevels[position];
            if (scale == caliper.map.MapScale)
                return;
                
            args.Command = "redraw_zoombar";
            caliper.map.zoomTargetScale = scale;    
            }
            
        args.MapScale = caliper.map.zoomTargetScale;
        caliper.map.clickImageHandler(args); 
        
        }
    };    
    
caliper.map.zoomPlus = function(evt) {
    var args = [];
    var position;
    var slideValue = 101 - jQuery("#zoomBar").slider("value");  
    

    position = parseInt(slideValue / 100 * caliper.map.zoomLevels.length);
    if (position >= caliper.map.zoomLevels.length) {
        caliper.map.zoomTargetScale = caliper.map.zoomLevels[caliper.map.zoomLevels.length -2];
        caliper.map.onZoomBarEnd(evt);            
        }
    else if (position >=1) {
        caliper.map.zoomTargetScale = caliper.map.zoomLevels[position -1];
        caliper.map.onZoomBarEnd(evt);            
        }
    };
            
caliper.map.zoomMinus = function(evt) {
    var args = [];
    var position;
    var slideValue = 101 - jQuery("#zoomBar").slider("value");  
    

    position = parseInt(slideValue / 100 * caliper.map.zoomLevels.length);
    if (position < caliper.map.zoomLevels.length-1) {
        caliper.map.zoomTargetScale = caliper.map.zoomLevels[position + 1];
        caliper.map.onZoomBarEnd(evt);            
        }
    };
            
//
// button event handlers
//
caliper.map.clickBookmark = function() {
    jQuery('#mapBookmarkTool').css("visibility","visible");
    };
    
caliper.map.clickButtonRestore = function() {
    caliper.map.clearPreviousMapHistory();
    caliper.map.resetMap();
    };
    
caliper.map.clickButtonZoomin = function() {
    caliper.map.command = 'zmin';
    caliper.map.mouseUpHandler = "caliper.map.clickImageHandler({Command:caliper.map.command})";
    caliper.map.selectButton(caliper.map.command);

    caliper.map.clearTools();
    };
    
caliper.map.clickButtonZoomout = function() {
    caliper.map.command = 'zmout';
    caliper.map.mouseUpHandler = "caliper.map.clickImageHandler({Command:caliper.map.command})";
    caliper.map.selectButton(caliper.map.command);

    caliper.map.clearTools();
    };
    
caliper.map.clickButtonPan = function() {
    caliper.map.command = 'pan';
    caliper.map.mouseUpHandler = "caliper.map.clickImageHandler({Command:caliper.map.command})";
    caliper.map.selectButton(caliper.map.command);

    caliper.map.clearTools();
    };
    
caliper.map.clickButtonInfo = function() {
    caliper.map.command = 'info';
    caliper.map.mouseUpHandler = "caliper.map.clickImageHandler({Command:caliper.map.command})";
    caliper.map.selectButton(caliper.map.command);

    caliper.map.clearTools();
    };
    
    
    
 /**
  *  Highlight one of the buttons above the map and set the current action (zoom, pan, info, select, measure...)
  *  If action_name is null, then select the current button.
  *  @param {String} action_name
  */
caliper.map.selectButton = function(command_name) {
    
    var buttons = jQuery('.gisdk_buttons');
    var b, img, id, prefix;
    for (var i=0;i<buttons.length;i++)
    {
        b   = jQuery(buttons[i]);
        id  = b.attr("id");                     // id = "gisdk_action_name_button"
        img = b.attr("src");
        prefix = img.substring(0,img.length-5)  // translate "info1.gif" to "info"
        if (id.indexOf("_"+command_name+"_")>0)
        {
            // the button id matches "command_name"
            caliper.map.command = command_name;
            img = prefix + "2.gif";
            if (caliper.map.mapContainer) caliper.map.mapContainer.style.cursor = b.attr("gisdk_cursor");
        }
        else
        {
            // the button id is another button
            img = prefix + "1.gif";
        }
        b.attr("src",img);
        }
    };
    
   
   
/** 
 * reset the application - map image, map scope, map url, and send message to other
 * controls that a reset is in process
 */
caliper.map.resetMap = function() {
    caliper.map.clickImageHandler({Command:"resetMap"});
    };
    
/**
 * Collect current tool command and coordinates, map scope and map width/height, send them to server
 * to update map
 */
caliper.map.clickImageHandler = function(args) {

    var rect_value = caliper.map.shapeRect;
    var pan_value  = caliper.map.shapePan;
    var request = caliper.map.getArguments();

    var command = args.Command;
    var initScope = args.InitScope; 

    caliper.map.showProgressbar();    
    if (typeof command == 'undefined') command = "update_map";
    
    if (command) {
        //if (!rect_value && !pan_value) return;

        request.Command =  command;
        if (command == 'resetMap') {
            //passing a null as map scope so that the map will be displayed in its
            //initial scope
            request.MapScope = null;
            request.InitScope = null;
            }
        else {
            request.Rect =  rect_value;
            request.PanShift = pan_value;
            }
        }
        
    if (typeof(initScope) != 'undefined' && initScope != null) 
        request.MapScope = initScope;
    else if (CCUtil.getGisdkProperties("NewMapScope") == "True"){ //map file is from a different folder
        request.MapScope = null;
        //clear NewMapScope flag
        CCUtil.setGisdkProperties({NewMapScope:null});
        }

    
    if (typeof(args.MapScale) != "undefined" && args.MapScale > 0) 
        request.MapScale = args.MapScale;
        
    //Image file format and image quality (for jpg files) may be set here
    //to override the settings in MapControl.config
    //request.ImageFormat = "PNG" or "JPG"
    //request.ImageQuality = 85
            
    request.ConfigFile = "MapControl.config";
        
    self.status = "Please wait...";

    if (command == 'info') {
        if (caliper.info) {
        //broadcast the event message so that subscribed listeners will handle
        jQuery("div.listener").trigger("MSG_getInfo",new Array(request)); 
        }
        else if (request.Rect != null && typeof (request.Rect) == "string") {
            caliper.map.hideProgressbar();
            var temp = request.Rect.split("|");
            if (temp != null && temp.length > 2)
                alert("Add an InfoControl to handle the event MSG_getInfo on mouse click x:"+temp[0]+", y:"+temp[1]);
            }
        }
    else
        caliper.mapService.DoMethod("MapService.RedrawMap", request, "MapControl.config", "MapControl", caliper.map.handler.onCompleteUpdateMap);
    };  


caliper.map.onCompleteMeasuring = function (response) {
    if (response.Message != "OK") {
        alert(response.Message);
        return;
        }
    
    var arguments = {};
    arguments.area = response.Area;
    arguments.area_sqkm = response.AreaSqkm;
    
    jQuery("div.listener").trigger("MSG_updateDistance",new Array(arguments));  
        
    };
    
//build JSON object of map width, height, scope and command, and annotation 
caliper.map.getArguments = function() {
    var map_args = CCUtil.getGisdkProperties();
    
    //remove pass-once items
    map_args.ImageFile = null;
    map_args.BoundingBox = null;
    map_args.InitMap = null;
    map_args.InitScope = null;
    map_args.MapScale = null;
    map_args.ZoomLevel = null;
    
    map_args.Command = caliper.map.command;
    map_args.ImageWidth = caliper.map.ImageWidth;
    map_args.ImageHeight =  caliper.map.ImageHeight;
    map_args.MapScope = caliper.map.MapScope;

    if ((typeof(caliper.Annotation) == "object") && (caliper.Annotation != null )) {
        var lon = parseFloat(caliper.Annotation.Lon) * 1000000;
        var lat = parseFloat(caliper.Annotation.Lat) * 1000000;
        map_args.AnnotationCoord = new Array(lon,lat);
    }
    else
        map_args.AnnotationCoord = null;

    return map_args;
    };

caliper.map.clearTools = function() {
    if (caliper.map.shapeToolContainer)
        caliper.map.shapeToolContainer.clearAll();
    };


caliper.map.clearPreviousMapHistory = function() {
    var prevMapButton = jQuery("#gisdk_previous_button");
    var pimg = prevMapButton.attr("preload");

    if (pimg && pimg.length > 5) prevMapButton.attr("src", pimg);
    
    caliper.map.mapScopeHistory = [];
    };

caliper.map.addToPreviousMapHistory = function(scope_string) {
    var prevMapButton = jQuery("#gisdk_previous_button");
    var simg = prevMapButton.attr("active");

    if (simg && simg.length > 5) prevMapButton.attr("src", simg);

    if ( caliper.map.mapScopeHistory.length > caliper.map.MAX_MAP_HISTORY)
        caliper.map.mapScopeHistory.shift();  //removes the earliest scope object from the array

    caliper.map.mapScopeHistory.push(scope_string);
    };
    
caliper.map.clickBackToPreviousMap = function() {
    if (caliper.map.mapScopeHistory.length == 0) return;
    
    var request = caliper.map.getArguments();
    var prevMapButton = jQuery("#gisdk_previous_button");
    var simg = prevMapButton.attr("inactive");
    var mapScope = caliper.map.mapScopeHistory.pop();
    
    if (mapScope == caliper.map.MapScope ) {
        if (caliper.map.mapScopeHistory.length == 0) {
            prevMapButton.attr("src", simg);
            //save the scope of current map in hostory
            caliper.map.mapScopeHistory.push(mapScope);
            return;
            }
            
        //first time the Prev_Map button is clicked, the last scope in history object is the current map scope
        mapScope = caliper.map.mapScopeHistory.pop();
        }
        
    if (typeof(mapScope) == 'undefined' || mapScope == "") return;
    
    request.MapScope = mapScope;
    request.Command =  "prev_map";
    
    //set prev_map button image to be inactive
    if (caliper.map.mapScopeHistory.length == 0 && simg && simg.length > 5) {
        prevMapButton.attr("src", simg);
        //save the scope of current map in hostory
        caliper.map.mapScopeHistory.push(mapScope);
        }
        
    request.SkipMapHistory = true;

    caliper.map.showProgressbar();    
    
    caliper.mapService.DoMethod("MapService.RedrawMap", request, "MapControl.config", "MapControl", caliper.map.handler.onCompleteUpdateMap);
    };    

caliper.map.clickSaveExcel = function() {

    if (caliper.map.print_window && !caliper.map.print_window.closed) 
        caliper.map.print_window.close();
    
    caliper.map.print_window = window.open('SelectControl.PrintToExcel.aspx','PrintingWindow','width=800,resizable=yes,scrollbars=yes,toolbar=yes,location=yes,status=yes,menubar=yes');

    };
    
/**
 * Generate clear HTML table in the browser for printing.
 */
caliper.map.clickPrint = function() {
    var print_window;
    var window_contents;
    var info_print_handler = null; 
        if ( ( typeof(caliper.info) != 'undefined')  && ( typeof(caliper.info.print) == 'function' ) ) 
                info_print_handler = caliper.info.print;

    var select_print_handler = null;
        if ( (typeof(caliper.select) != 'undefined' ) && (typeof(caliper.select.print) == 'function' ) ) 
                select_print_handler = caliper.select.print; 


    if (caliper.map.print_window && !caliper.map.print_window.closed) 
        caliper.map.print_window.close();
    
    caliper.map.print_window = window.open('','PrintingWindow','width=800,resizable=yes,scrollbars=yes,toolbar=yes,location=yes,status=yes,menubar=yes');
    
    var print_window = caliper.map.print_window;
        
    if (typeof(print_window) != "undefined" && print_window != null) {
        window_contents = "<link rel='stylesheet' href='styles.css' type='text/css'/>";
        
        window_contents = window_contents + "<table border=0 width=100%>";
  
        window_contents = window_contents + "<tr><td bgcolor='#ffff99' class='font_black_big' align='center' height='35'>" + CCUtil.getGisdkProperties("MapFile") + "</td></tr>";
        
        window_contents = window_contents + "<tr><td valign='top'><img src='" + caliper.map.MapURL + "' border='1'><img src='" + caliper.map.MapLegendURL + "' border='1'></td></tr>";

        if (typeof (info_print_handler) != 'undefined' && info_print_handler != null) {
            var info_contents = info_print_handler();
            
            if (info_contents != null) {
                window_contents = window_contents + "<tr><td align='center' bgcolor='#99ff99' class='font_black_bold'>Info records</td></tr>";
                window_contents = window_contents + "<tr><td>"+info_contents+"</td></tr>";
                }
            }

        if (typeof (select_print_handler) != 'undefined' && select_print_handler != null) {
            var select_contents = select_print_handler();
            
            if (select_contents != null) {
                window_contents = window_contents + "<tr><td align='center' bgcolor='#99ff99' class='font_black_bold'>Selection records</td></tr>";
                window_contents = window_contents + "<tr><td>"+select_contents+"</td></tr>";
                }
            }

        window_contents = window_contents + "</table>";
                       
        print_window.document.write(window_contents);
        print_window.document.close();
        }
        
    };    
    
caliper.map.startMapDragging = function() {
        if (CCUtil) CCUtil.startToolboxDragging("mapWindow");
    };
        
caliper.map.startToolboxDragging = function() {
        if (CCUtil) CCUtil.startToolboxDragging("mapToolBox");
    };
    
caliper.map.relocateIcon = function() {
    jQuery("#LegendIcon").css("top", CCUtil.getBrowserSize().height - 50);
    jQuery("#LegendIcon").css("left", 0);
    };
        
caliper.map.hideMapLegend = function() {
    jQuery("#legendWindow").css("visibility", "hidden");
    jQuery("#LegendIcon").css("visibility", "visible");
    caliper.map.legendVisible = false;
    caliper.map.relocateIcon();
    };
        
caliper.map.showMapLegend = function() {
    jQuery("#legendWindow").css("visibility", "visible");
    jQuery("#LegendIcon").css("visibility", "hidden");
    caliper.map.legendVisible = true;
    };
        

updateIcons = function() {
    jQuery("#MinIconContainer").css("top", CCUtil.getBrowserSize().height - 50);
    };    
    
/**
 ** handlers for services and messages
 **/    
/**
 * Get pre-defined quick-zoom levels. If the level array is not defined in MapControl.config, use the default one.
 */
caliper.map.handler.onCompleteMapSettings = function(response) {
    var i, counter, zoomLevels;
    var LOW = 0, MID_LOW = 1, MEDIUM = 2, MID_HIGH = 3, HIGH=4;
    var height_shift = 10;
    
    caliper.map.ImageWidth  = response.ImageWidth;
    caliper.map.ImageHeight = response.ImageHeight;
    
    if (typeof(caliper.map.ImageWidth) == 'undefined' || caliper.map.ImageWidth == null || caliper.map.ImageWidth <= 0)
        caliper.map.ImageWidth = caliper.map.IMAGEWIDTH;
    if (typeof(caliper.map.ImageHeight) == 'undefined' || caliper.map.ImageHeight == null || caliper.map.ImageHeight <= 0)
        caliper.map.ImageHeight = caliper.map.IMAGEHEIGHT;
    
    if (typeof(response.ZoomLevels) == "string") {
        zoomLevels = response.ZoomLevels.split(",");

        if (zoomLevels.length == 1) //no parse
            zoomLevels = response.ZoomLevels.split(" ");

        if (zoomLevels.length > 1) {
            caliper.map.zoomLevels = new Array(); //empty array  
            counter = 0;
                  
            for (i=0; i< zoomLevels.length; i++) {
                zoomLevels[i] = zoomLevels[i].trim();
                if (zoomLevels[i] != "" && zoomLevels[i] != null) {
                    caliper.map.zoomLevels[counter] = parseInt(zoomLevels[i]);
                    counter ++;
                    }
                }      
            } //if (zoomLevels.length > 1)
        } //if (typeof(response.ZoomLevels) == "string")
        
    //adjust map image size according to screen resolution
    if (screen && typeof(response.AdjustMapSize) == "string" && response.AdjustMapSize.toUpperCase() == "YES" ) {
        if (screen.height >= 1024) {
            caliper.map.ImageWidth  = caliper.map.mapSizes[HIGH]; //650
            caliper.map.ImageHeight = caliper.map.mapSizes[HIGH];
            }
        else if (screen.height >= 768) {
            caliper.map.ImageWidth  = caliper.map.mapSizes[MID_HIGH]; //500
            caliper.map.ImageHeight = caliper.map.mapSizes[MID_HIGH];
            }
        else if (screen.height >= 600) {
            caliper.map.ImageWidth  = caliper.map.mapSizes[MEDIUM]; //350
            caliper.map.ImageHeight = caliper.map.mapSizes[MEDIUM];
            }
        else {
            caliper.map.ImageWidth  = caliper.map.mapSizes[MID_LOW]; //300
            caliper.map.ImageHeight = caliper.map.mapSizes[MID_LOW];
            }
        }    
    caliper.map.mapCenter = {x: caliper.map.ImageWidth / 2, y: caliper.map.ImageHeight / 2};
    
    caliper.map.mapContainer = dojo.byId("imgspan");

    if (CCUtil.BrowserDetect.browser == "Firefox" && CCUtil.BrowserDetect.version == 3)
        jQuery("#imgspan").css("position", "absolute");

    //create map image surface object on which map tools can draw rectangles, marks and circles
    caliper.map.mapSurface = dojox.gfx.createSurface(caliper.map.mapContainer,caliper.map.ImageWidth , caliper.map.ImageHeight);
    caliper.map.mapSurface.createRect({width: caliper.map.ImageWidth, height: caliper.map.ImageHeight});

    if (typeof (map_image_obj) != 'undefined') caliper.map.mapSurface.remove(map_image_obj);
    map_image_obj = null;

    if (typeof(caliper.chooseMap) == 'undefined') {
        map_image_obj = caliper.map.mapSurface.createImage({width: caliper.map.ImageWidth, height: caliper.map.ImageHeight, src: caliper.map.MapURL});
        caliper.map.mapSurface.add(map_image_obj);
        }

    var args = {
        "map_width":  caliper.map.ImageWidth,
        "map_height": caliper.map.ImageHeight,
        "surface":    caliper.map.mapSurface};
    CCUtil.init(args);
    caliper.map.shapeToolContainer = new CCUtil.selectionToolContainer({snapDist: caliper.map.SNAP_DISTANCE});


    if (!dojo.isIE) height_shift = 70;
    
    //adjust map frame width
    //jQuery("#mapWindow").css("left", caliper.map.MAPWINDOWINITX);
    //jQuery("#mapWindow").css("top", CCUtil.getControlPosition("MapControl"));
    jQuery("#mapWindow").css("width",caliper.map.ImageWidth + 5);
    jQuery("#mapWindow").css("height",caliper.map.ImageHeight + height_shift);
    jQuery("#imgtable").css("height",caliper.map.ImageHeight);
    
    //jQuery("#mapToolBox").css("left",0);
    //jQuery("#mapToolBox").css("top", CCUtil.getControlPosition("MapControl"));

    // caliper.map.adjustZoomBarPosition();

    //initialize map parameters: map_url, map_scope
    if (typeof(caliper.chooseMap) == "undefined") {
        //set this callback message so that other controls (i.e. SelectControl) will be updated
        caliper.map.updateMapCallbackMessages = ["MSG_completeSelectingMap"];
        if (typeof(caliper.layers) != 'undefined' && caliper.layers != null)
            jQuery("div.listener").trigger("MSG_updateLayer", new Array(arguments));
        else caliper.map.handler.redrawMap(null, null);
        }

    //send message that the map image surface is ready
    jQuery("div.listener").trigger("MSG_completeMapSurface",null);  
    };

/**
 * gets called when other controls want to update map
 */
caliper.map.handler.redrawMap = function (event, arg)
    {
    if (arg == null) arg = {};
    
    if (arg.callbackMessages != null)
        caliper.map.updateMapCallbackMessages = arg.callbackMessages;

    if (arg.ImageFile) caliper.map.handler.onCompleteUpdateMap(arg);
    else 
        caliper.map.clickImageHandler(arg);
    };


/**
 * Update positions of map toolbox and legend pane
 */
    caliper.map.handler.updatePosition = function() {
        return;
    };
    
/**
 * After the toolbox is moved (dragged), check if it is in docking position, and change the toolbar color accordingly.
 * The actual position of the toolbox is adjusted by the MSG_updateToolboxPosition message sent from CCUtil.checkDocking()
 */
caliper.map.checkToolboxDocking = function() {
    if (CCUtil.checkDocking({top:jQuery("#mapToolBox").attr("offsetTop"), left:jQuery("#mapToolBox").attr("offsetLeft"), ControlName:"MapControl"})) 
        jQuery("#mapToolBox .title_bar").each(function() {
            this.className = "title_bar_dock";
            });
    else 
        jQuery("#mapToolBox .title_bar_dock").each(function() {
            this.className = "title_bar";
            });
    
    };


// activate the legend tab    
caliper.map.activate_legend = false;

/**
 * Update map image and legend image (if applicable), record current map scope and scale,
 * send messages to update other controls.
 */
caliper.map.handler.onCompleteUpdateMap = function(response)
    {
    var targetMapWindow = null;
    var mapWidth, mapHeight;
    var imageSpanObj = null;
    var mapLegendObj = jQuery("#legendWindow #map_legend");
    var mapLegendWindow = jQuery("#legendWindow");
    var mapScaleDiv = jQuery("#mapScale");
    var mapScopeSegs, mapScopeWidth, mapScopeHeight;

    if (response == null) return;
    if (response.Message != "OK") {
        alert(response.Message);
        self.status = "Ready";
        return;
        }
       
    // store the last gisdk response in a global javascript object   
    if (response) 
    {
        // update contents in gisdk_response
        CCUtil.setGisdkProperties(response);
       
        if (response.MapScope && (typeof (response.SkipMapHistory) == 'undefined' || response.SkipMapHistory == null)) 
            caliper.map.addToPreviousMapHistory(response.MapScope);
        
        CCUtil.setGisdkProperties({SkipMapHistory: null});
            
    }

   if (response.Annotation & typeof(response.Annotation) == "array") { 
       caliper.Annotation = response.Annotation;
   }

   if ( response.MapFile && typeof(response.MapFile) == "string")
    {
        var map_name = response.MapFile;
        map_name = map_name.replace(/\\data\\/ig,"");
        map_name = map_name.replace(/\.map/ig,"");
        map_name = map_name.replace(/\\/ig, " - ");
        if ( map_name.indexOf("ccessMaps")>0 )
        {
            map_name = "Baltimore map";
        }
        jQuery("#map_name").html( map_name );
        caliper.map.MapTitle = map_name;
    }
        
    if (response && response.ImageFile && caliper.map.mapSurface )
        {
        //reset and recreate map image object
        caliper.map.MapURL   = caliper.map.GisdkTempFileFolder + response.ImageFile;
        caliper.map.MapScope = response.MapScope;
        caliper.map.MapScale = response.MapScale;
        
        jQuery("#zoomValue").attr("value",caliper.map.MapScale);
    
        if (map_image_obj) caliper.map.mapSurface.remove(map_image_obj);
        map_image_obj = null;

        map_image_obj = caliper.map.mapSurface.createImage({width: caliper.map.ImageWidth, height: caliper.map.ImageHeight, src: caliper.map.MapURL});
        caliper.map.mapSurface.add(map_image_obj);

        if (response.Command != 'redraw_zoombar')  caliper.map.adjustZoomBarLevel();
        
        mapScopeSegs = response.MapScope.split(" ");
        if (mapScopeSegs != null && mapScopeSegs.length == 5) {
            mapScopeWidth = Math.round(mapScopeSegs[2] * 100) / 100;
            mapScopeHeight = Math.round(mapScopeSegs[3] * 100) / 100;

            mapScaleDiv.html(" Scale: 1:"+response.MapScale + " Center: Longitude "+mapScopeSegs[0]+" Latitude "+mapScopeSegs[1]+" size " +mapScopeWidth+" x "+mapScopeHeight+" " +mapScopeSegs[4]);
            }
        else
            mapScaleDiv.html(" Scale: 1:"+response.MapScale + " Scope: "+response.MapScope+"");
        
        //legend image
        if (response.HideLegend || caliper.map.legendVisible == false) mapLegendWindow.css("visibility","Hidden");
        else if (typeof(response.LegendFile) == 'undefined' || response.LegendFile == null)
            mapLegendWindow.css("visibility","Hidden");
        else if (mapLegendObj[0]) {
            mapLegendWindow.css("visibility","visible");
            mapLegendObj.css("visibility","visible");
            caliper.map.MapLegendURL = caliper.map.GisdkTempFileFolder + response.LegendFile;
            mapLegendObj[0].src = caliper.map.MapLegendURL;
            if (caliper.map.activate_legend)
            {
                jQuery("#accordion_panels").accordion("activate",1);
                caliper.map.activate_legend = false;
            }
        }
        
        //display map image object
        if (caliper.map.mapContainer) caliper.map.mapContainer.style.visibility="visible";
        
        //fire complete_updating_map message, controls may need to update themselves upon
        //the changes of the map (i.e. LayerControl needs to disable/enable layers in the list depending on
        //the display status of the layers
        jQuery("div.listener").trigger("MSG_completeUpdatingMap");

        //fire up callback messages if any
        if (caliper.map.updateMapCallbackMessages) {
            var message, i;
            for (i=0; i<caliper.map.updateMapCallbackMessages.length; i++) {
                message = caliper.map.updateMapCallbackMessages[i];
                jQuery("div.listener").trigger(message);
                }
                
            //clear the list so the call-backs won't be triggered over and over    
            caliper.map.updateMapCallbackMessages = null;
            }
        }

    caliper.map.hideProgressbar();            
    self.status = "Ready";
        
    } ;

caliper.map.handler.closePrintWindow = function () {
    if (caliper.map.print_window && !caliper.map.print_window.closed) 
        caliper.map.print_window.close();

    };
        

/**
 ** Public functions
 **/    
 caliper.map.showProgressbar = function(timeout_limit) {
    if (typeof(timeout_limit) == 'undefined' || timeout_limit == null)
        timeout_limit = 3000; //3 seconds;
    else if (timeout_limit < 0 || timeout_limit > 60)
        timeout_limit = 15000; //15 seconds;
    else
        timeout_limit = timeout_limit * 1000;
        
    //turn on progress indicator, and set timer to turn if off after 15 seconds if it's not been hidden by
    //caliper.select.handler.onCompleteSelectApply(). 
    jQuery('#Progress_indicator').css("visibility", "visible");            
    setTimeout("caliper.map.hideProgressbar()", timeout_limit);
    };
    
 caliper.map.hideProgressbar = function() {
    jQuery('#Progress_indicator').css("visibility", "hidden");            
    };
    
caliper.map.getControlPaneHeight = function() {
    //height of map toolbox
    return 52;
    };    

