var mapEngine = {
  mouseDown : 0, 
  mouseDownZoom : 0,
  posX : 10,
  posY : 0,
  posZoomX : 10,
  posZoomY : 0, 
  lastMoveZoom : 0,
  lastPosX : 0,
  lastPosY : 0,
  curVieportX: 0,
  curVieportY: 0,
  buttonScrollStep: 10,
  mapWidth: 0,
  mapHeight: 0,  
  rows: 0,
  cols: 0,
  areaWidth: 0,
  areaHeight: 0,
  zoom: 1,
  scale: 1,
  scaleFactor: 1,
  imgMapsPath: "",
  mapDirectory: "",
  partWidth: 0,
  partHeight: 0,
  ext: "",
  zooms: "", //obejct with zooms data
  zoomsCnt: 0,
  arguments: "",  
  streetObjects: { id: 0, x: 0, y: 0},
  timerObj : null
}

mapEngine.prototype = {}

mapEngine.mapMouseUp = function() {
  this.mouseDown = 0;
}

mapEngine.mapMouseDown = function() { 
  this.mouseDown = 1;             
}  

mapEngine.mapMouseMove = function() {    
  if (this.mouseDown == 1)
  {         
    var top = document.getElementById("parts").style.top;
    var left = document.getElementById("parts").style.left;
    
    top = top.replace('px','') * 1;
    left = left.replace('px','') * 1;

    var deltaX = this.lastPosX - this.posX;
    var deltaY = this.lastPosY - this.posY;
    
    top -= deltaY;
    left -= deltaX;
    
    if (top > 0)
      top = 0;

    var maxTop = -1 * (this.mapHeight - this.areaHeight);
    if (top < maxTop)
      top = maxTop;

    if (left > 0)
      left = 0;

    var maxLeft = -1 * (this.mapWidth - this.areaWidth);      
    if (left < maxLeft)
      left = maxLeft;
    
    document.getElementById("parts").style.top = top+"px";
    document.getElementById("parts").style.left = left+"px";
    
    mapEngine.curVieportX = left;
    mapEngine.curVieportY = top;

    this.addParts(left, top);        
    
    if (mapEngine.isPathCanvas())
    {
      $('#pathArea').css({
        "left": left+"px", 
        "top": top+"px",
        "position": "absolute"
        })       
     // pathEngine.objects.translate(-1 * deltaX, -1 * deltaY);      
      /*document.getElementById("pathArea").style.position = "absolute";
      document.getElementById("pathArea").style.top = top+"px";
      document.getElementById("pathArea").style.left = left+"px";*/      
    }
  }
}

mapEngine.mapZoomMove = function() {    
  if (this.mouseDownZoom == 1) {    
//    alert(mapEngine.posOffY);
    var id = Math.floor((this.posZoomY-mapEngine.offsetTop) / 18) + 1;    
    if (id != mapEngine.offsetTop)
    {
      $('#zoom #levels').children().attr('src','apl/html/images/zoom_level_off.png').removeClass('zoom_step_cur').addClass('zoom_step');
      $('#zoom_'+id).attr('src','apl/html/images/zoom_level_on.png').removeClass('zoom_step').addClass('zoom_step_cur');
      mapEngine.lastMoveZoom = id;
    }
//    document.write('a');
  }
}   

mapEngine.moveMap = function(goUp, goRight, goDown, goLeft) {
  var top = document.getElementById("parts").style.top;
  var left = document.getElementById("parts").style.left;
  
  top = top.replace('px','') * 1;
  left = left.replace('px','') * 1;

  if (goUp)      
    top += this.buttonScrollStep;

  if (goRight)        
    left += this.buttonScrollStep;

  if (goDown)      
    top += -1 * this.buttonScrollStep;

  if (goLeft)        
    left += -1 * this.buttonScrollStep;
  /*
  if (top > 0)
    top = 0;

  var maxTop = -1 * (this.mapHeight - this.areaHeight);
  if (top < maxTop)
    top = maxTop;

  if (left > 0)
    left = 0;

  var maxLeft = -1 * (this.mapWidth - this.areaWidth);      
  if (left < maxLeft)
    left = maxLeft;   
  */
  
  correctedVieport = this.correctViewport(left, top);
  
  left = correctedVieport[0];
  top = correctedVieport[1];
  document.getElementById("parts").style.top = top+"px";
  document.getElementById("parts").style.left = left+"px";  
  
  mapEngine.curVieportX = left;
  mapEngine.curVieportY = top;
  
  this.addParts(left, top);
}

mapEngine.correctViewport = function(left, top) {
  if (top > 0)
    top = 0;

  var maxTop = -1 * (this.mapHeight - this.areaHeight);
  if (top < maxTop)
    top = maxTop;

  if (left > 0)
    left = 0;

  var maxLeft = -1 * (this.mapWidth - this.areaWidth);      
  if (left < maxLeft)
    left = maxLeft;   
  
  var out = new Array(2);
  out[0] = left;
  out[1] = top;
  
  return out;
}

mapEngine.addParts = function(left, top) {
  //calculate new area an parts
  //get print area
  minX = -1*left;
  maxX = -1*left + this.areaWidth;
  minY = -1*top;
  maxY = -1*top + this.areaHeight;

  partDeltaStartX = Math.floor(minX / this.partWidth);
  partDeltaEndX = Math.ceil(maxX / this.partWidth);
  partDeltaStartY = Math.floor(minY / this.partHeight);
  partDeltaEndY = Math.ceil(maxY / this.partHeight);                     
  
  partsCount = this.cols * this.rows;
  for (j = partDeltaStartY ; j < partDeltaEndY ; j++)
  {            
    for (i = partDeltaStartX ; i < partDeltaEndX ; i++)
    {
      partNum = j * this.cols + i + 1;
      if (partNum < 10)
        partNum = '0'+partNum;          
      filename = this.imgMapsPath+this.mapDirectory+"/zoom_"+this.zoom+"/"+partNum+"."+this.ext;           
      left = i * this.partWidth;
      top = j * this.partHeight;
      
     // document.write($('#part_'+$partNum));
      if ($('#part_'+partNum).length == 0 && partNum <= partsCount && partNum > 0)
      {
        //document.write('aaa');
        $('#parts').append('<img src="'+filename+'" style="position: absolute; left: '+left+'px; top: '+top+'px;" class="map_part" id="part_'+partNum+'"/> ');
        //$('#streets').append("<br/>"+$filename+"<br/>"+$left+"<br/>"+$top+"<br/>"+$partNum);
       // $('#streets1').append("<br/>"+$partNum);
      }
    }
  }     
}

//trans coordinates from base scale to another
//return array (corrected and uncorrected cooridnates)
mapEngine.transformCoordinates = function (scale, left, top) {
  if (typeof(top) == 'undefined')
  {      
    top = document.getElementById("parts").style.top;            
    top = top.replace('px','') * 1;      
  }
  if (typeof(left) == 'undefined')
  {
    left = document.getElementById("parts").style.left;
    left = left.replace('px','') * 1;  
  }    
  
  if (scale < 1)
  {
    left -= (mapEngine.areaWidth/2);      
    top -= (mapEngine.areaHeight/2);
    /*
    if (left > 0)
      left = 0;
    if (top > 0)
      top = 0;
    */
    top *= scale;        
    left *= scale;   
    
    left += (mapEngine.areaWidth/2);      
    top += (mapEngine.areaHeight/2);
    
    /*if (scale < 0.5 && false)
    {
      left += (mapEngine.areaWidth * scale);
      top += (mapEngine.areaHeight * scale);
    }*/
  }
  else if (scale > 1)
  {        

    left -= (mapEngine.areaWidth/2);      
    top -= (mapEngine.areaHeight/2);
    /*
    if (left > 0)
      left = 0;
    if (top > 0)
      top = 0;
    */
    top *= scale;        
    left *= scale;   
    
    left += (mapEngine.areaWidth/2);      
    top += (mapEngine.areaHeight/2);
  }   
  
  correctedVieport = mapEngine.correctViewport(left, top);      
        
  var out = new Array(4);
  out[0] = correctedVieport[0];
  out[1] = correctedVieport[1];    
  out[2] = left;
  out[3] = top;
  
  return out;
}

mapEngine.zoomChange = function (zoom) {        
  newZoom = mapEngine.zoom;
  //set new zoom value
  if (zoom == '+')
    newZoom = mapEngine.zoom - 1;
  if (zoom == '-')
    newZoom = mapEngine.zoom + 1;
  if (!isNaN(zoom))
    newZoom = zoom;      
    
  if (newZoom > mapEngine.zoomsCnt || newZoom < 1 || newZoom == mapEngine.zoom)
  {
//    alert('nothing to do');
    return;
  }
      
  var i, n = arguments.length;
  mapEngine.arguments = new Array();
  for (i = 0; i < n; i += 1) 
  {
    mapEngine.arguments.push(arguments[i]);
  }
    
  ajax.callUrl(new Array(new Array('action','zoomChange')), this.zoomChangeCallback)
}

mapEngine.zoomChangeCallback = function() {
  var path = false;
  
  if(ajax.req.readyState == 4) {
    //clear paths
    if (mapEngine.isPathCanvas())
    {
      pathEngine.removeCanvas();
      path = true;
    } 
    var response = ajax.req.responseText;    
//    alert(ajax.req.responseText);
    mapEngine.zooms = eval('(' + ajax.req.responseText + ')');
//    alert(mapEngine.zooms[2].width);
    
    var zoom = mapEngine.arguments[0];
    var oldZoom = mapEngine.zoom;
    newZoom = mapEngine.zoom;
    //set new zoom value
    if (zoom == '+')
      newZoom = mapEngine.zoom - 1;
    if (zoom == '-')
      newZoom = mapEngine.zoom + 1;
    if (!isNaN(zoom))
      newZoom = zoom;      
      
    if (newZoom > mapEngine.zoomsCnt)
      newZoom = mapEngine.zoomsCnt;
    if (newZoom < 1)
      newZoom = 1;
    
//    alert(newZoom);
    mapEngine.zoom = newZoom;
    newZoom -= 1;
    
    var oldScale = mapEngine.scale;
    var oldMapWidth = mapEngine.mapWidth;
    var oldMapHeight = mapEngine.mapHeight;
    
    mapEngine.mapHeight = +mapEngine.zooms[newZoom].height;
    //set local variables
    mapEngine.mapWidth = +mapEngine.zooms[newZoom].width;
    mapEngine.mapHeight = +mapEngine.zooms[newZoom].height;      
    mapEngine.partWidth = +mapEngine.zooms[newZoom].part_width;      
    mapEngine.partHeight = +mapEngine.zooms[newZoom].part_height;
    mapEngine.rows = +mapEngine.zooms[newZoom].rows;      
    mapEngine.cols = +mapEngine.zooms[newZoom].cols;            
    mapEngine.ext = mapEngine.zooms[newZoom].ext;
    mapEngine.scale = +mapEngine.zooms[newZoom].scale;
    
    jQuery(".map_part").remove();
    
    var scale = mapEngine.scale/oldScale;
   
    mapEngine.scaleFactor = scale;
    
    cords = mapEngine.transformCoordinates(scale);            
    left = +cords[0];
    top1 = +cords[1];

    $('#parts').css({
      "left": left+"px", 
      "top": top1+"px"
      }) 
//    document.getElementById("parts").style.top = top+"px";
//    document.getElementById("parts").style.left = left+"px";  
    
    mapEngine.addParts(left, top1); 
    
    newZoom += 1;
    $('#zoom_'+oldZoom).attr('src','apl/html/images/zoom_level_off.png').removeClass('zoom_step_cur').addClass('zoom_step');
    $('#zoom_'+newZoom).attr('src','apl/html/images/zoom_level_on.png').removeClass('zoom_step').addClass('zoom_step_cur');
    
    //recalculate position of markers
    $('.map_marker').each(function() {
//      alert(scale);
      top1 = $(this).css("top");            
      top1 = top1.replace('px','') * 1 * scale;      
    
      left = $(this).css("left");
      left = left.replace('px','') * 1 * scale;  
      
//      cords = mapEngine.transformCoordinates(scale, left, top);
//      cords2 = mapEngine.showMarker('DUMMY', cords[2], cords[3])
      $(this).css({
        "left": left+"px", 
        "top": top1+"px"
        })         
    });
    
    if (path)
      pathEngine.drawsPathsAfterZoom();
    //var resp = response.getElementsByTagName("response");
    //getObject("offer_col_right").innerHTML = response;    
  }
  //if(ajax.req.readyState == 1 || ajax.req.readyState == 0)
    //getObject("offer_col_right").innerHTML = '<p class="paragraph_short">adowanie danych...</p>';    

  //if(ajax.req.readyState != 1 && ajax.req.readyState != 0 && ajax.req.readyState != 4)
      //getObject("offer_col_right").innerHTML = '<p class="paragraph_short"></p>';
}

mapEngine.getMarkerCallback = function() {
  if(ajax.req.readyState == 4) 
  {
    var response = ajax.req.responseText;
    
    html = eval('(' + ajax.req.responseText + ')');
    //alert(ajax.req.responseText);
    $('#parts').append(html.marker);
    $('#map').append(html.popup);
    
    $('a[rel=fancybox]').fancybox({
      'frameWidth':    230, 
     'frameHeight': 100,
     'hideOnContentClick': false}
    );
          
    $('.tooltip').tooltip({ 
        track: true, 
        delay: 0, 
        showURL: false, 
        showBody: " - ", 
        fade: 250 
    });      
  }
}

mapEngine.init = function() {
  
  this.mapHeight = controller.opt.mapHeight;
  this.mapWidth = controller.opt.mapWidth;
  
  jQuery(document).ready(function() {
    $().mousemove(function(e){
      mapEngine.posX = e.pageX;
      mapEngine.posY = e.pageY;
            
      /*if (posX < 10 || posX > 408)
       mouseDown = 0;
      if (posY < 31 || posY > 512)
       mouseDown = 0;*/
                                 
       //if x,y > poza ramka mapy to mouseDown = 0;
    }); 
         
    $("#parts").mousemove(function(e){      
      mapEngine.lastPosX = mapEngine.posX;
      mapEngine.lastPosY = mapEngine.posY;
      mapEngine.posX = e.pageX;
      mapEngine.posY = e.pageY;      
      mapEngine.mapMouseMove();
      return false; 
       //if x,y > poza ramka mapy to mouseDown = 0;
    });
    
    $("#parts").dblclick(function(e){
      var oldZoom = mapEngine.zoom;
      newZoom = mapEngine.zoom - 1;
        
      if (newZoom >= 0)
        mapEngine.zoomChange(newZoom);
      
    });
    
    $("#zoom #levels").mousemove(function(e){
      mapEngine.lastPosX = mapEngine.posZoomX;
      mapEngine.lastPosY = mapEngine.posZoomY;
      mapEngine.posZoomX = e.pageX;
      mapEngine.posZoomY = e.pageY;      
      mapEngine.offsetTop = this.offsetTop;      
      mapEngine.mapZoomMove();
      return false; 
       //if x,y > poza ramka mapy to mouseDown = 0;
    });     
 })
 
 $().mouseup(function(){     
   if (mapEngine.mouseDownZoom == 1)
     mapEngine.zoomChange(mapEngine.lastMoveZoom);
   mapEngine.mouseDown = 0;
   mapEngine.mouseDownZoom = 0;
   controller.mouseDown = 0;   
   });
   
   $("#map").mousedown(function(){       
     $('#suggestions').fadeOut();

     //alert('mb'+controller.j);
     //alert(controller.mouseDown);
     
     if (controller.mouseDown == 0)
       mapEngine.mouseDown = 1;
      return false;
   });
   
   $("#zoom #levels").mousedown(function(){       
     $('#suggestions').fadeOut();

     //alert('mb'+controller.j);
     //alert(controller.mouseDown);
     
     if (controller.mouseDown == 0)
       mapEngine.mouseDownZoom = 1;
      return false;
   });   
   
   $("#zoom #levels").mouseup(function(){      
//     alert( mapEngine.mouseDownZoom);
//     if (controller.mouseDown == 1 && mapEngine.mouseDownZoom == 1)
//      alert(mapEngine.lastMoveZoom);
//      return false;
   });   
}

mapEngine.printMap = function() {
  var html = '<HTML>\n<HEAD>\n<meta http-equiv="content-type" content="text/html; charset=utf-8" /><link rel="stylesheet" href="./apl/html/css/print.css" type="text/css"/><link rel="stylesheet" type="text/css" href="./apl/html/css/jquery.fancybox.css" media="screen" /><link rel="stylesheet" type="text/css" href="./apl/html/css/jquery.tooltip.css" media="screen" />';
      
  html += '\n</HE' + 'AD>\n<BODY>\n';
  
  var printReadyElem = document.getElementById("content");
  
  if (printReadyElem != null)
  {
      html += printReadyElem.innerHTML;
  }
  else
  {
    alert("Błąd wydruku");
    return;
  }
    
  html += '\n</BO' + 'DY>\n</HT' + 'ML>';
  
  var printWin = window.open("","printSpecial");
  printWin.document.open();
  printWin.document.write(html);
  printWin.document.close();
  if (true)
    printWin.print();  
}

mapEngine.showObject = function (caller, type, showMarker, showMode, x, y, id) {
  var cords, posX, posY, objId, spanStreetObjects, tag, objLabel;
  
  if (typeof(x) != 'undefined' || typeof(y) != 'undefined' || typeof(id) != 'undefined')
  {
    posX = -1 * x;
    posY = -1 * y;
    objId = id;              
  }
  else
  {
    selectId = '#'+type+'_Select';    
    if ($(selectId).length > 0)
    {
      cords = $(selectId).val().split("_");
      posX = -1 * cords[0];
      posY = -1 * cords[1];
      objId = cords[2];
      //TODO obsluga bledow
    }
    else
        return;
  }
   
  switch (type)
  {
    case 'S': //ulica             
      //rememeber id and text to enable showstreetobjects
      tag = caller.get(0).tagName.toLowerCase();
      
      switch (tag)
      {
        case 'select':
          objLabel = caller.find(':selected').text();
          break;
        case 'a':
          objLabel = caller.find('span.searchheading').text();          
          break;          
      }
      
      spanStreetObjects = $('#a_street_objects span');
      spanStreetObjects.text(objLabel);
      this.streetObjects.id = objId;
      this.streetObjects.x = posX;      
      this.streetObjects.y = posY;      
      break;
  }

  this.clearMarkers();
  //calculate coordinates
  //TODO move to function (also used id showpath)
  cords = mapEngine.transformCoordinates(mapEngine.scale, posX + mapEngine.areaWidth/2, posY  + mapEngine.areaHeight/2);
  left = cords[0];
  top1 = cords[1];
  
  //go to position    
  //move or jump?    
  document.getElementById("parts").style.left = left+"px";  
  document.getElementById("parts").style.top = top1+"px";
  
  //clear last pointer?
  //show pointer?
  mapEngine.addParts(left, top1); 
  
  mapEngine.showMarker(objId, type, cords[2], cords[3], showMarker, showMode);
}

//show marker or only transform cooridnates
mapEngine.showMarker = function (id, type, left, top, showMarker, showMode) {
  var marker, image;    
  var parts = $('#parts');
  
  //translate coordinates
  left = -1 * left + mapEngine.areaWidth/2;
  top = -1 * top + mapEngine.areaHeight/2;
  switch (type)
  {
    case 'SS': //ulica        
      //clear data
      if (showMarker = 'Y')
      {
        var label = $("#S_Select option:selected").attr("label");
        jQuery(".marker_"+type).remove();
        jQuery(".popup_marker_"+type).remove();
        // when fancybox put direct image?
        marker = $("<a></a>").addClass("marker_"+type).addClass("marker_link").attr('title',label);
        /*   
        marker.tooltip({ 
             track: true, 
             delay: 0, 
             showURL: false, 
             showBody: " - ", 
             fade: 250 
         });
          */      
        image = $(new Image()).attr('src','./apl/html/images/markers/pointer_st.png').css({
          "position": "absolute", 
          "left": left+"px", 
          "top": top+"px"
          }).addClass("map_marker");
        marker.append(image);
        parts.append(marker);
      }
      break;        
    default:
      jQuery(".marker_"+type).remove();
      jQuery(".popup_marker_"+type).remove();
//      alert(mapEngine.scaleFactor);
      // get marker data from db
      ajax.callUrl(new Array(new Array('action','getMarker'), new Array('id',id), new Array('scale', mapEngine.scale)), this.getMarkerCallback)
      break;
  }    
  
  var out = new Array(2);
  out[0] = left;
  out[1] = top;
  
  return out;    
}

mapEngine.showAllObjects = function (type) {    
  mapEngine.showMarker(type, type, 0, 0, '', '');
}

mapEngine.showStreetObjects = function() {
  if (this.streetObjects.id == 0)
  {
    alert("Najpierw wyszukaj ulicę.");
    return;
  }
  
  this.clearMarkers();
  
  cords = mapEngine.transformCoordinates(mapEngine.scale, this.streetObjects.x + mapEngine.areaWidth/2, this.streetObjects.y  + mapEngine.areaHeight/2);
  left = cords[0];
  top1 = cords[1];
  
  //go to position    
  //move or jump?    
  document.getElementById("parts").style.left = left+"px";  
  document.getElementById("parts").style.top = top1+"px";
  
  //clear last pointer?
  //show pointer?
  mapEngine.addParts(left, top1);   
//  jQuery(".marker_"+type).remove();
//  jQuery(".popup_marker_"+type).remove();
  ajax.callUrl(new Array(new Array('action','getStreetObjects'), new Array('id',this.streetObjects.id), new Array('scale', mapEngine.scale)), this.getMarkerCallback);  
}

mapEngine.clearMarkers = function() {
  jQuery(".marker_link").remove();
  jQuery(".popup_marker").remove();
  
  if (this.isPathCanvas())
    pathEngine.removeCanvas();
}

mapEngine.selectKeyPress = function() {
  mapEngine.timer = true;     
}

mapEngine.selectClick = function() {
  mapEngine.timer = false;     
}

mapEngine.selectChange = function(a,b,c,d) {
  if (mapEngine.timer)
  {
    delay = 1000;
    clearTimeout( mapEngine.timerObj );
    mapEngine.timerObj = setTimeout( function(){mapEngine.showObject(a,b,c,d);}, delay );
//    mapEngine.timerObj = setTimeout( "alert('a');", delay );
  }
  else
  {
    clearTimeout( mapEngine.timerObj );
    mapEngine.showObject(a,b,c,d);
  }
}

mapEngine.isPathCanvas = function() {
  if (typeof(pathEngine) != 'undefined' && $('#pathArea').length > 0)
    return true;
  
  return false;
}