/**
 * GMap2.showBounds() method. Fit bounds to viewport with paddings.
 * @ author Esa 2008
 * @ param bounds_ GLatLngBounds()
 * @ param opt_options Optional options object {top, right, bottom, left}
 */
GMap2.prototype.showBounds = function(bounds_, opt_options){
  var opts = opt_options||{};
  opts.top = opts.top*1||0;
  opts.left = opts.left*1||0;
  opts.bottom = opts.bottom*1||0;
  opts.right = opts.right*1||0;
  
  var port = this.getSize();
  
  
  var portBounds = new GLatLngBounds();
  portBounds.extend(this.fromContainerPixelToLatLng(new GPoint(opts.left, port.height-opts.bottom)));
  portBounds.extend(this.fromContainerPixelToLatLng(new GPoint(port.width-opts.right, opts.top)));
  return portBounds;
}
/**
 * SidebarGControl.js
 * By: Alan Hietala
 * July 16th 2009
 * Description: This control renders the planeteye sidebar out and handles events raised by the map
 * Object.
 * Events it responds to in the map object are moveend and the custom event planeteye.category.change.
 * Requires: Jquery 1.2.6, map-services.js 
 */
function SidebarGControl(initialCat, selfServePlace, customerId){
    this.categoryCode = initialCat;
    this.selfServePlace = selfServePlace;
    this.customerId = customerId;
    
    // maximum number of elements displayed in the sidebar at once
    // this is hardcoded and must match that of the webservices..
    this.sidebarmax = 25;   
}

SidebarGControl.prototype = new GControl()
SidebarGControl.prototype.currentPage = 1;


/**
 * Init Function called by the map when the control is added
 * all events are bound here etc...
 */
 
SidebarGControl.prototype.initialize = function(map){
   
    // set up the ajax request queue for the sidebar			
    this.requestQueue = new Array();

    var sidebarActual = document.createElement('div');
    $(sidebarActual).addClass('sidebarActual');

    var sidebarGrip = document.createElement('div');
    $(sidebarGrip).addClass('sidebarGrip'); 
    $(sidebarGrip).html("<div class='x' style='margin-top: " + (map.getSize().height/2).toString() + "px;'>&laquo;</div>");



    // create the div to write content into 
    var category = "tescategory";
    var sidebardiv = document.createElement("div");
    $(sidebardiv).addClass("mapSidebar");
    // mattm: set height dynamically, so we can adjust the embedded map size
    $(sidebardiv).attr('style', 'height: ' + (map.getSize().height).toString() + 'px;');
   
    
    var contents = $(document.createElement("div"));
    contents.addClass("sidebarContents");
    // mattm: set height to = map height - 60px
    contents.attr('style', 'height: ' + (map.getSize().height-30).toString() + 'px;');
    
    var footer = $(document.createElement("div"));
    footer.addClass("sidebarFooter");

    var pinfo = $(document.createElement("div"));
    pinfo.addClass("sidebarPInfo");
    pinfo.html("<span class='q'>Page</span> <span class='sidebarCurrentPageNum'>1</span>");

    var pcontrol = $(document.createElement("div"));
    pcontrol.addClass("sidebarPControl");

    var prev = $(document.createElement("a"));
    prev.html("previous");
    prev.attr("href","#");
    prev.addClass("sidebarPagingPrev");
    var thisObj = this;
    prev.click(function(){
      if ($(this).hasClass('sidebarPagingPrevDisabled')) return false;
      thisObj.prevPage();
      return false;
    });
    
    var next = $(document.createElement("a"));
    next.html("next");
    next.attr("href","#");
    next.addClass("sidebarPagingNext");
    next.click(function(){
      if ($(this).hasClass('sidebarPagingNextDisabled')) return false;
      thisObj.nextPage();
      return false;
    });

    pcontrol.append(next);
    pcontrol.append(prev);
    pcontrol.append("<div class='clear'></div>");
    footer.append(pinfo);  
    footer.append(pcontrol);
    footer.append("<div class='clear'></div>");

    $(sidebarActual).append(contents);
    $(sidebarActual).append(footer);
    $(sidebardiv).append(sidebarActual);
    $(sidebardiv).append(sidebarGrip);
    $(sidebardiv).append("<div class='clear'></div>");
    
    this.sidebarcontainer = contents;
    map.getContainer().appendChild(sidebardiv);

    // store handles to the sidebar in the map
    map._sidebar = this;
    map._sidebar_dom_object = sidebardiv;

    // attach the map move listen event
    var obj = this;
    
    // on a real map move, we need to reset the page counter back to the beginning.
    GEvent.addListener(map,"moveend",function(){obj.currentPage = 1; obj.mapmoved_(map);});
    GEvent.addListener(map,"planeteye.category.change",function(tabEvent){obj.changecat_(map,tabEvent);});
    return sidebardiv;
}

/**
 * Gets the default position of the control. This is set to the left side of the map.
 */
SidebarGControl.prototype.getDefaultPosition = function(){

    return new GControlPosition(G_ANCHOR_TOP_LEFT, new GSize(0, 0));



}

/**
 * This Control should print when the page is printed
 */
SidebarGControl.prototype.printable = function(){return true;}

/**
 * This Control's text is selectable
 */
SidebarGControl.prototype.selectable = function(){return true;}

/**
 * Function to run on map move event
 */
SidebarGControl.prototype.mapmoved_ = function(map){
    this.cancelRequests();
    // clear the sidebar of event handlers
    this.sidebarcontainer.find(".sidebarItem").unbind("click");
    
    this.sidebarcontainer.html("");
    this.map = map;
    var opts = {top:20,right:20,bottom:20,left:310,disableSetCenter:true};
    var bounds = map.showBounds(map.getBounds(),opts);
    

    
  

//    var southWest = bounds.getSouthWest();
//	var northEast = bounds.getNorthEast();


      var sw = bounds.getSouthWest();
      var ne = bounds.getNorthEast();
      
      var east = 179.999;
      var west = -179.999;
      var north = 89.999;
      var south = -89.999;
     
      // is the whole lat range visible on the map?  (pole to pole) 
      if (!map.getBounds().isFullLat()) {
        north = ne.lat();
        south = sw.lat();
      }
      
      // is the whole lng range visible on the map?  east to west?
      if (!map.getBounds().isFullLng()) {
        east = ne.lng();
        west = sw.lng();
      }	
	
	
	
    //var north = northEast.lat()==90 ? 89.99 : northEast.lat();
    //var south = southWest.lat() == -90 ? -89.00 : southWest.lat();
    //var east = northEast.lng() == 180 ? 179.99 : northEast.lng();
    //var west = southWest.lng() == -180 ? -179.99 : southWest.lng();
    var zoom = map.getZoom();
   
    // at zoom level 2, google seems to reverse the east/west lng values
    /*
    if (zoom <= 2) {
      west = northEast.lng();
      east = southWest.lng();
      
      if (zoom == 1 && west > east) {
          var tmp = east;
          east = west;
          west = tmp;
      }
    }
    */
   
    if(this.categoryCode == "photos"){ // handle photos
        planeteye.map.services.getSidebarPhotos(north,south,east,west,zoom, this.currentPage,this.customerId,this.photoSuccessHandler_,this.photoFailureHandler_,this,this.requestQueue);
    
    // this is a travel pack request
    }else if(this.categoryCode.indexOf("map")>-1){
        planeteye.map.services.getTravelPackItemsForArea(north,south,east,west,zoom, 100,  this.currentPage,  -1,  parseInt(this.categoryCode.split(".")[1]), this.customerId, this.buildTpkHTML,function(){},this,this.requestQueue);
        
    // this is a single location, entered from the self-serve page
    } else if (this.categoryCode.indexOf("single.location") > -1) {
        this.placeSuccessHandler_([this.selfServePlace], this);
        
    }else{ // handle places
        planeteye.map.services.getSidebarPlaces(north,south,east,west,zoom, this.currentPage,this.customerId,this.categoryCode,this.placeSuccessHandler_,this.placeFailureHandler_,this,this.requestQueue);
    }
    
    
}

SidebarGControl.prototype.setupPaging_ = function(xhr, args) {

    var paging = args.sidebarcontainer.parents(".mapSidebar").find(".sidebarFooter");

    paging.find(".sidebarCurrentPageNum").html(args.currentPage);

    var prev = paging.find(".sidebarPagingPrev");
    var next = paging.find(".sidebarPagingNext");

    var pdis = 'sidebarPagingPrevDisabled';
    var ndis = 'sidebarPagingNextDisabled';

    // we're on the first page
    //
    if (args.currentPage == 1) {
      prev.addClass(pdis);
    } else {
      prev.removeClass(pdis);
    }
    
    // we're on the last page
    //
    if (xhr.length < args.sidebarmax) { 
      next.addClass(ndis);
    } else {
      // there is a next page
      next.removeClass(ndis);
    }

}

/**
 * The Success Handler to pass to the place ajax call for the sidebar
 */
SidebarGControl.prototype.placeSuccessHandler_ = function(xhr,args){
   if (xhr.length > 0) {
      for(var x = 0;x<xhr.length;x++){
         args.sidebarcontainer.append(args.getPlaceHTML_(xhr[x],args.map));
      }
   } else {
      //args.sidebarcontainer.append('<div class="sidebarempty" style="padding: 10px;"><strong>No places found</strong><br/>Try zooming out to view more of the area.</div>');
      args.sidebarcontainer.append('<div class="sidebarItem"><div class="itemAttributes"><div class="itemTitle">No places found</div><div class="itemWrapper"><div class="itemDesc">Try zooming out to view more of the area.</div></div></div>');
   }
    args.setupPaging_(xhr, args);
}
/**
 * The Success Handler to pass to the photo ajax call for the sidebar
 */
SidebarGControl.prototype.photoSuccessHandler_ = function(xhr,args){
    for(var x = 0;x<xhr.length;x++){
        args.sidebarcontainer.append(args.getPhotoHTML_(xhr[x],args.map));
    }
    args.setupPaging_(xhr, args);
}
/**
 * The Failure Handler to pass to the place ajax call for the sidebar
 */
SidebarGControl.prototype.placeFailureHandler_ = function(xhr,args,code){
    


}


/**
 * The Failure handler to pass to the photos ajax call for the sidebar
 */
SidebarGControl.prototype.photoFailureHandler_ = function(xhr,args,code){
    


}
/**
 * Function to run on changecat event. This will refresh the sidebar using the new category.
 * Paging will be reset to page 1 when this is called.
 */
SidebarGControl.prototype.changecat_ = function(map,tabEvent){
   
    this.categoryCode = tabEvent.sidebar;
    
    this.currentPage = 1;
    this.mapmoved_(this.map);
}



/**
 * Creates the HTML for a a single place in the sidebar
 */
SidebarGControl.prototype.getPlaceHTML_ = function(place, map){


    var item = $(document.createElement("div"));
    item.addClass("sidebarItem");
    
    var itemattr = $(document.createElement("div"));
    itemattr.addClass("itemAttributes");
   
    
    var itemwrap = $(document.createElement("div"));
    itemwrap.addClass("itemWrapper");

    var itemtitle_wrap = $(document.createElement("div"));
    itemtitle_wrap.addClass("itemTitle");
    var itemtitle = $(document.createElement("div"));
    itemtitle.html(place.Title);
    
     var itemDesc = $(document.createElement("div"));
    itemDesc.addClass("itemDesc");
    // deal with the 'null'
    itemDesc.html((place.Description == null ? '' : place.Description) + " <span style='color:#DE9585; text-decoration:underline;'>more &raquo;</span>");
    
    var itemCategory = $(document.createElement("div"));
    itemCategory.addClass("itemCategory");
    itemCategory.html(place.CategoryName);
    
    var itemAddress = $(document.createElement("div"));
    itemAddress.addClass("itemAddress");
    itemAddress.html(place.Address);
  
    if (place.ThumbnailUrl && place.ThumbnailUrl != '') {
        var itemPhoto= $(document.createElement("div"));
        itemPhoto.addClass("itemPhoto");
        itemPhoto.html("<img src='" + place.ThumbnailUrl + "' alt='' />"); 
    } 
    
    var clearTheDiv= $(document.createElement("div"));
    clearTheDiv.addClass("divClear"); 
   

    //var itemDesc = $(document.createElement("div"));
    //var details = place.Description!=""? place.Description : place.Address;
    //var details = '';
    //if (place.Description && place.Description != null && place.Description != "")
    //{
    //    details = place.Description;
    //} else {
     //   details = place.Address;
    //}
    //itemDesc.html(details);
    //itemDesc.addClass("itemDesc");

    // var itemlinks = $(document.createElement("div"));
    //itemlinks.addClass("itemLinks");
    
    
    itemtitle_wrap.append(itemtitle);
    itemattr.append(itemtitle_wrap);
    itemwrap.append(itemPhoto);
    itemwrap.append(itemDesc)
    itemwrap.append(itemCategory);
    itemwrap.append(itemAddress);
    itemattr.append(itemwrap);
   itemattr.append(clearTheDiv); 
    item.append(itemattr);
    
    //item.append(itemlinks);
    

    var thisObj = this;

    // attach events that will trigger map actions...    
    item.unbind('click');
    item.unbind('mouseover');
    item.unbind('mouseout');
    item.bind('click',function(){
       GEvent.trigger(map,'planeteye.map.dot.' + place.DotId + '.open', 'place.' + place.PlaceId);
    });
    item.bind('mouseover',function(){
       thisObj.hiliteOn(this);
       GEvent.trigger(map,'planeteye.map.dot.' + place.DotId + '.hover.on');
    });
    item.bind('mouseout',function(){
       thisObj.hiliteOff(this);
       GEvent.trigger(map,'planeteye.map.dot.' + place.DotId + '.hover.off');
    });
    
    return item;                
}


/**
 * Creates the HTML for a a single photo in the sidebar
 */
SidebarGControl.prototype.getPhotoHTML_ = function(photo,map){
    
    var item = $(document.createElement("div"));
    item.addClass("sidebarItem");

    var itemimg_wrap = $(document.createElement("div"));
    itemimg_wrap.addClass("sidebarImage");
    
    var itemimg = $(document.createElement("img"));
    itemimg.attr("src",photo.Url);

    itemimg_wrap.append(itemimg);    
    item.append(itemimg_wrap);

    var thisObj = this;    
    
    item.unbind('click');
    item.unbind('mouseover');
    item.unbind('mouseout');
    
    item.bind("click",function(){
      GEvent.trigger(map,'planeteye.map.dot.' + photo.DotId + '.open', 'photo.' + photo.MediaId);
    });
    
    item.bind('mouseover',function(){
       thisObj.hiliteOn(this);
       GEvent.trigger(map,'planeteye.map.dot.' + photo.DotId + '.hover.on');
    });
    item.bind('mouseout',function(){
       thisObj.hiliteOff(this);
       GEvent.trigger(map,'planeteye.map.dot.' + photo.DotId + '.hover.off');
    });


    return item;                
}


SidebarGControl.prototype.hiliteOn = function(div) {
  $(div).addClass('itemHilite');
}

SidebarGControl.prototype.hiliteOff = function(div) {
  $(div).removeClass('itemHilite');
}


SidebarGControl.prototype.nextPage = function(){
    this.currentPage ++;
    this.mapmoved_(this.map);
    
}


SidebarGControl.prototype.prevPage = function(){
    this.currentPage --;
    this.mapmoved_(this.map);
}


/**
 * Cancels all pending ajax requests for the sidebar. Prevents multiple requests from
 * running at the same. Don't forget to add your requests to the requestQueue when you make them.
 */
SidebarGControl.prototype.cancelRequests = function(){
    while(this.requestQueue.length>0){
        this.requestQueue.pop().abort();
    }

}


/**
 * Creates the HTML to insert in the list view container
 * based on the items retrieved via the ajax call
 *
 * TODO - this should be the same as 'getPlaceHTML_' and 'getPhotoHTML_'
 */
SidebarGControl.prototype.buildTpkHTML = function (xhr,args){
    var container = args.sidebarcontainer;
    var count = parseInt(xhr.data.mediawall_data["@totalmedia"]) + parseInt(xhr.data.places["@totalplaces"]);
    if(xhr.data.mediawall_data["@totalmedia"]>1){
        
        for(var i in xhr.data.mediawall_data.mediaitem){
            
            container.append(args.buildTpkPhotoElement(xhr.data.mediawall_data.mediaitem[i], args));
        }
    }else if(xhr.data.mediawall_data["@totalmedia"]==1){
        container.append(args.buildTpkPhotoElement(xhr.data.mediawall_data.mediaitem, args));
    }
    if(xhr.data.places["@totalplaces"]>1){
        for(var j in xhr.data.places.place){
            container.append(args.buildTpkPlaceHTML(xhr.data.places.place[j], args));
        }
    }else if(xhr.data.places["@totalplaces"]==1){
        container.append(args.buildTpkPlaceHTML(xhr.data.places.place, args));
    }else if(count==0){
        container.append("<div class='tpkmessage'>There are no locations in this map view.</div>");
    }
  
    //return theList;
}
   
   
/**
 * Creates the HTML to insert in the list view container
 * for a place item that is passed in from a travel pack
 */
SidebarGControl.prototype.buildTpkPlaceHTML = function (place, args){
   
    var xplace = {};
    
    xplace.Title = place.title;
    xplace.CategoryName = place.categories['@MainCategoryName'];
    xplace.Description = place.description;
    xplace.Address = place.address;
    xplace.DotId = 'place.' + place['@id'];
    xplace.PlaceId = '';
    
    return this.getPlaceHTML_(xplace, args.map);
}


/**
 * Creates the HTML for a photo element in the travelpack item list
 */
SidebarGControl.prototype.buildTpkPhotoElement = function(photo, args) {

    var xphoto = {};
    
    xphoto.Url = 'http://' + photo['@pathSlice'];
    xphoto.MediaId = photo['@mediaid'];
    xphoto.DotId = 'photo.' + photo['@mediaid'];

    return this.getPhotoHTML_(xphoto, args.map);     
}

