
function DragMeasureControl(opts_boxStyle, opts_other, opts_callbacks) {
  // Holds all information needed globally
  // Not all globals are initialized here
  this.globals = {
    draggingOn: false,
    mapPosition: null,
    mapWidth: 0,
    mapHeight: 0,
    mapRatio: 0,
    lastX: 0,
    lastY: 0,
    borderCorrection: 0,
    pointAdded: false,
    polyPoints: [],
    polyShape: null,
    polyShapeY: null
  };

  //box style options
  this.globals.style = {
    opacity: 0,
    fillColor: "#ffffff",
    border: "2px solid blue"
  };

  var style = this.globals.style;
  for (var s in opts_boxStyle) {
    style[s]=opts_boxStyle[s];
  }

  var borderStyleArray = style.border.split(' ');
  style.outlineWidth = parseInt(borderStyleArray[0].replace(/\D/g,''));
  style.outlineColor = borderStyleArray[2];
  style.alphaIE = 'alpha(opacity=0)';
 
  // Other options
  this.globals.options={
   stickyZoomEnabled: true
  };
	
  for (var s in opts_other) {
    this.globals.options[s] = opts_other[s]
  }

  // callbacks: buttonclick, dragstart, dragging, dragend
  if (opts_callbacks == null) {
    opts_callbacks = {}
  }
  this.globals.callbacks = opts_callbacks;
}
try
{
    DragMeasureControl.prototype = new GControl();
}
catch (ex)
{
}
/**
 * Method called to initiate a dragMeasure as if the user had clicked the dragMeasure button.
 */
DragMeasureControl.prototype.initiateMeasure = function() {this.buttonclick_()};

DragMeasureControl.prototype.resetMeasure = function() {this.resetDragMeasure_()};

/**
 * Is called by GMap2's addOverlay method. Creates the measure control
 * divs and appends to the map div.
 * @param {GMap2} map The map that has had this DragMeasureControl added to it.
 * @return {DOM Object} Div that holds the gmeasurecontrol button
 */ 
DragMeasureControl.prototype.initialize = function(map) {
  var G = this.globals;
  var me = this;
  var mapDiv = map.getContainer();
  G.polyPoints = [];
  G.draggingOn == false;
  // Create div for both buttons	
    var buttonContainerDiv = document.createElement("div");	
 
  //DOM:map covers
    var measureDiv = document.createElement("div");
    measureDiv.id ='gmeasure-map-cover';
    measureDiv.innerHTML = '';
    DragMeasureUtil.style([measureDiv], {position: 'absolute', display: 'none', overflow: 'hidden', cursor: 'crosshair', zIndex: 101});
    mapDiv.appendChild(measureDiv);
  
  // add event listeners
    GEvent.addDomListener(measureDiv, 'click', function(e) {
      me.coverClick_(e);
    });
    GEvent.addDomListener(measureDiv, 'dblclick', function(e) {
      me.coverDblClick_(e);
    });
    GEvent.addDomListener(measureDiv, 'mousemove', function(e) {
      me.coverMouseMove_(e);
    });

  
  // get globals
    G.mapPosition = DragMeasureUtil.getElementPosition(mapDiv);
    G.mapCover = DragMeasureUtil.gE("gmeasure-map-cover");
    G.map = map;
  
    G.borderCorrection = G.style.outlineWidth * 2;	
    this.setDimensions_();
  
  //styles
    this.initStyles_();

  // disable text selection on map cover
    G.mapCover.onselectstart = function() {return false}; 
    
  return buttonContainerDiv;
};

/**
 * Required by GMaps API for controls. 
 * @return {GControlPosition} Default location for control
 */
DragMeasureControl.prototype.getDefaultPosition = function() {
  return new GControlPosition(G_ANCHOR_TOP_LEFT, new GSize(3, 120));
};

DragMeasureControl.prototype.coverClick_ = function(e){
    var G = this.globals;
    var pos = this.getRelPos_(e);
    var pnt = G.map.fromContainerPixelToLatLng(new GPoint(pos.left, pos.top));
    //var distanceType = document.getElementById("distanceSelect").text;
    var selObj = document.getElementById('distanceSelect');
    var selIndex = selObj.selectedIndex;
	var distanceType = selObj.options[selIndex].value;
	//txtTextObj.value = selObj.options[selIndex].text;
    if (selectedTool != "point")
    {
        G.polyPoints.push(pnt);
        G.draggingOn = true;
        if (G.lastX != 0 || G.lastY != 0)
        {
            if (selectedTool == "polygon")
            {
                try
                {
                    G.map.removeOverlay(G.polyShape);
                    //G.map.removeOverlay(G.polyShapeY);
                }
                catch (ex) { }
                G.polyPoints.push(G.polyPoints[0]);
                G.polyShape = new GPolygon(G.polyPoints, "#FF0000", 3, opacity, "#000000", opacity);
                G.polyPoints.pop();
                G.map.addOverlay(G.polyShape);
            }
            else if (selectedTool == "line")
            {
            
            
                try
                {
                    G.map.removeOverlay(G.polyShape);
                    //G.map.removeOverlay(G.polyShapeY);
                }
                catch (ex) { }
                
//                var pnt = G.map.fromContainerPixelToLatLng(new GPoint(G.lastX, G.lastY));
//                var pnt2 = G.map.fromContainerPixelToLatLng(new GPoint(pos.left, pos.top));
//                var newPoints = [];
//                newPoints.push(pnt);
//                newPoints.push(pnt2);
                
                G.polyShape = new GPolyline(G.polyPoints, "#FF0000", 3, opacity);
                //G.polyShapeY = new GPolyline(newPoints, "#FF0000", 3, opacity);
                G.map.addOverlay(G.polyShape);
                //G.map.addOverlay(G.polyShapeY);
            
            
            
            
            }
        }
        G.lastX = pos.left;
        G.lastY = pos.top;
    }
    else
    {
        try
        {
            G.map.removeOverlay(G.polyShape);
            G.map.removeOverlay(G.polyShapeY);
        }
        catch (ex) { }
        calcPoint(pnt.lng(), pnt.lat());
        G.polyShape = new GMarker(new GLatLng(pnt.lat(), pnt.lng()));
        G.map.addOverlay(G.polyShape);
    }
    return false;
};

DragMeasureControl.prototype.coverDblClick_ = function(e) {
    if (selectedTool != "point")
    {
        var G = this.globals;
        try
        {
            G.map.removeOverlay(G.polyShape);
            G.map.removeOverlay(G.polyShapeY);
        }
        catch (ex) { }
        var selObj = document.getElementById('distanceSelect');
        var selIndex = selObj.selectedIndex;
	    var distanceType = selObj.options[selIndex].value;
        if (selectedTool == "polygon") {
            G.polyPoints.push(G.polyPoints[0]);
            polyShapeY = new GPolyline(G.polyPoints, lineColor, 3, opacity);
            var length = polyShapeY.getLength()/1000;
            length = convertTo(length, distanceType, "Kilometers");
            
            polyShapeX = new GPolygon(G.polyPoints, lineColor, 3, opacity, "#000000", opacity);
            G.polyShape = polyShapeX;
            var area = polyShapeX.getArea();
            area = convertAreaTo(area, distanceType);
            //area = convertTo(area, distanceType, "Kilometers");
            var square = "";
            if (distanceType != "Hectares" && distanceType != "Ares" && distanceType != "Acres")
                square = "Square ";
            document.getElementById('measureresults').innerHTML = "Area: " + area + " " + square + distanceType + "<br /><br />Length: " + length + " " + distanceType;
            activateMeasureTool("polygon");
            //document.getElementById("distanceSelect").value = distanceType;
        }
        else if (selectedTool == "line") {
            var polyShapeY = new GPolyline(G.polyPoints, lineColor, 3, opacity);
            G.polyShape = polyShapeY;
            var length = polyShapeY.getLength()/1000;
            length = convertTo(length, distanceType, "Kilometers");
            document.getElementById('measureresults').innerHTML = length + " " + distanceType;
            activateMeasureTool("line");
            //document.getElementById("distanceSelect").value = distanceType;
        }
        G.draggingOn = false;
        G.map.addOverlay(G.polyShape);
        googlePoints = G.polyPoints;
        G.polyPoints = [];
    }
    return false;
};

DragMeasureControl.prototype.coverMouseMove_ = function(e) {
    if (selectedTool != "point")
    {
        var G = this.globals;
        var pos = this.getRelPos_(e);
        if (G.draggingOn == true)
        {
            try
            {
                //G.map.removeOverlay(G.polyShape);
                G.map.removeOverlay(G.polyShapeY);
            }
            catch (ex) { }
            
            var pnt = G.map.fromContainerPixelToLatLng(new GPoint(G.lastX, G.lastY));
            var pnt2 = G.map.fromContainerPixelToLatLng(new GPoint(pos.left, pos.top));
            var newPoints = [];
            newPoints.push(pnt);
            newPoints.push(pnt2);
            
            if (selectedTool == "polygon")
            {
//                G.polyPoints.push(G.polyPoints[0]);
//                G.polyShape = new GPolygon(G.polyPoints, "#FF0000", 3, opacity, "#000000", opacity);
//                G.polyPoints.pop();
            }
            else if (selectedTool == "line") {
                //G.polyShape = new GPolyline(G.polyPoints, "#FF0000", 3, opacity);
            }   
            G.polyShapeY = new GPolyline(newPoints, "#FF0000", 3, opacity);
            //G.map.addOverlay(G.polyShape);
            G.map.addOverlay(G.polyShapeY);
        }
    }
    return false;
};


/**
 * Set the cover sizes according to the size of the map
 */
DragMeasureControl.prototype.setDimensions_ = function() {
  var G = this.globals;
  var mapSize = G.map.getSize();
  G.mapWidth  = mapSize.width;
  G.mapHeight = mapSize.height;
  G.mapRatio  = G.mapHeight / G.mapWidth;
  // set left:0px in next <div>s in case we inherit text-align:center from map <div> in IE.
  DragMeasureUtil.style([G.mapCover], 
    {left: '0px',width: G.mapWidth + 'px', height: G.mapHeight +'px'});
};

/**
 * Initializes styles based on global parameters
 */
DragMeasureControl.prototype.initStyles_ = function(){
  var G = this.globals;
  DragMeasureUtil.style([G.mapCover], 
    {filter: G.style.alphaIE, opacity: G.style.opacity, background:G.style.fillColor});
  //G.outlineDiv.style.border = G.style.border;  
};

/**
 * Function called when the measure button's click event is captured.
 */
DragMeasureControl.prototype.buttonclick_ = function(){
  var G = this.globals;	
  if (G.mapCover.style.display == 'block') { // reset if clicked before dragging 
    this.resetDragMeasure_();
    this.initCover_();
  } else {
    this.initCover_();
  }
};

/**
 * Shows the cover over the map
 */
DragMeasureControl.prototype.initCover_ = function(){
  var G = this.globals;
  G.mapPosition = DragMeasureUtil.getElementPosition(G.map.getContainer());
  this.setDimensions_();
//  this.setButtonMode_('measureing');
  DragMeasureUtil.style([G.mapCover], {display: 'block', background: G.style.fillColor});
  //DragMeasureUtil.style([G.outlineDiv], {width: '0px', height: '0px'});

  //invoke callback if provided
//  if(G.callbacks['buttonclick'] != null){
//    G.callbacks.buttonclick();
//  }
};

/**
 * Gets position of the mouse relative to the map
 * @param {Object} e
 */
DragMeasureControl.prototype.getRelPos_ = function(e) {
  var pos = DragMeasureUtil.getMousePosition(e);
  var G = this.globals;
  return {top: (pos.top - G.mapPosition.top), 
          left: (pos.left - G.mapPosition.left)};
};

/**
 * Figures out the rectangle the user's trying to draw
 * @param {Number} startX 
 * @param {Number} startY
 * @param {Object} pos
 * @param {Number} ratio
 * @return {Object} Describes the rectangle
 */
//DragMeasureControl.prototype.getRectangle_ = function(startX, startY, pos, ratio){
//  var left = false;
//  var top = false;
//  var dX = pos.left - startX;
//  var dY = pos.top - startY;	
//  if (dX < 0) {
//    dX = dX * -1;
//    left = true;
//  }
//  if (dY < 0) {
//    dY = dY * -1;
//    top = true;
//  }
//  delta = dX > dY ? dX : dY;

//	//alper aşağıdaki değerleri değiştirdi.
//  return {
//    startX: startX,
//    startY: startY,
//    endX: startX + dX,
//	endY: startY + dY,
//    width: dX,
//	height: dY,
//    left:left,
//    top:top
//  }
//};

/** 
 * Resets CSS and button display when drag measure done
 */
DragMeasureControl.prototype.resetDragMeasure_ = function() {
    try
    {
        var G = this.globals;
        try
        {
            G.map.removeOverlay(G.polyShape);
            G.map.removeOverlay(G.polyShapeY);
        }   
        catch (ex) { }
        DragMeasureUtil.style([G.mapCover], 
            {display: 'none', opacity: G.style.opacity, filter: G.style.alphaIE});
        G.polyPoints = [];
        G.draggingOn == false;
        //G.outlineDiv.style.display = 'none';	
    
    }
    catch (ex)
    {
    }
//  this.setButtonMode_('normal');
};

/* utility functions in DragMeasureUtil.namespace */
var DragMeasureUtil={};

/**
 * Alias function for getting element by id
 * @param {String} sId
 * @return {Object} DOM object with sId id
 */
DragMeasureUtil.gE = function(sId) {
  return document.getElementById(sId);
}

/**
 * A general-purpose function to get the absolute position
 * of the mouse.
 * @param {Object} e  Mouse event
 * @return {Object} Describes position
 */
DragMeasureUtil.getMousePosition = function(e) {
  var posX = 0;
  var posY = 0;
  if (!e) var e = window.event;
  if (e.pageX || e.pageY) {
    posX = e.pageX;
    posY = e.pageY;
  } else if (e.clientX || e.clientY){
    posX = e.clientX + 
      (document.documentElement.scrollLeft ? document.documentElement.scrollLeft : document.body.scrollLeft);
    posY = e.clientY + 
      (document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop);
  }	
  return {left: posX, top: posY};  
};

/**
 * Gets position of element
 * @param {Object} element
 * @return {Object} Describes position
 */
DragMeasureUtil.getElementPosition = function(element) {
  var leftPos = element.offsetLeft;          // initialize var to store calculations
  var topPos = element.offsetTop;            // initialize var to store calculations
  var parElement = element.offsetParent;     // identify first offset parent element  
  while (parElement != null ) {                // move up through element hierarchy
    leftPos += parElement.offsetLeft;      // appending left offset of each parent
    topPos += parElement.offsetTop;  
    parElement = parElement.offsetParent;  // until no more offset parents exist
  }
  return {left: leftPos, top: topPos};
};

/**
 * Applies styles to DOM objects 
 * @param {String/Object} elements Either comma-delimited list of ids 
 *   or an array of DOM objects
 * @param {Object} styles Hash of styles to be applied
 */
DragMeasureUtil.style = function(elements, styles){
  if (typeof(elements) == 'string') {
    elements = DragMeasureUtil.getManyElements(elements);
  }
  for (var i = 0; i < elements.length; i++){
    for (var s in styles) { 
      elements[i].style[s] = styles[s];
    }
  }
};

/**
 * Gets DOM elements array according to list of IDs
 * @param {String} elementsString Comma-delimited list of IDs
 * @return {Array} Array of DOM elements corresponding to s
 */
DragMeasureUtil.getManyElements = function(idsString){		
  var idsArray = idsString.split(',');
  var elements = [];
  for (var i = 0; i < idsArray.length; i++){
    elements[elements.length] = DragMeasureUtil.gE(idsArray[i])
  };
  return elements;
};


