/**
 * @author Lian Castellón
 * @copyright 2009 Mastropieros, Inc.
 */

var Main = {
  /**
   * A general helper function for creating html elements. <div> as default element type
   * @author Esa 2008 
   * used for infowindows and sidebar
   */
  createElem: function(opt_className, opt_html, opt_tagName)
  {
    var tag = opt_tagName||"div";
    var elem = document.createElement(tag);
    if (opt_html) 
    {
      elem.innerHTML = opt_html;
    }
    
    if (opt_className) 
    {
      elem.className = opt_className;
    }
    
    return elem;
  },  

  /**
   * Marker icon
   */
  tinyImage: function (opt_color, opt_preload)
  {
    var color = opt_color||"red";
    var src_ = "http://labs.google.com/ridefinder/images/mm_20_"+color+".png";
    if(opt_preload)
    {
      var preImage = new Image();
      preImage.src = src_;
    }
    
    return  src_;
  },
  
  tinyIcon: function (opt_color)
  {
    var tiny = new GIcon();
    tiny.image = this.tinyImage(opt_color);
    tiny.shadow = "http://labs.google.com/ridefinder/images/mm_20_shadow.png";
    tiny.iconSize = new GSize(12, 20);
    tiny.shadowSize = new GSize(22, 20);
    tiny.iconAnchor = new GPoint(6, 20);
    tiny.infoWindowAnchor = new GPoint(5, 1);
    tiny.imageMap = [4,0,0,4,0,7,3,11,4,19,7,19,8,11,11,7,11,4,7,0];
    tiny.transparent = "http://maps.google.com/mapfiles/transparent.png";
    
    return tiny;
  },

  /**
   * create infowindow
   */
  createInfoWindow: function(point, opt_options)
  {
    var opts = opt_options||{};
    var start = opts.iLabel||2;
    var iwNode = this.createElem("info-window");
    var iwRows = [];
    
    for (var i = start; i < point.textArray.length; i++)
    {
      var row = this.createElem("iw-cell-"+i, point.textArray[i]);
      iwRows.push(row);
      iwNode.appendChild(row);
    }
    
    iwRows[0].className += " iw-header";
    point.marker.bindInfoWindow( iwNode, {maxWidth: 300});
  },
  
  ajaxLoad: function(textFile, opt_options)
  {
    var opts = opt_options || {};
    opts.sidebar = myBar;
    
    var process = function(material)
    {
      var entries = material.parseCsv( material, opts);
      map.populate( entries, opts);
    };
    
    GDownloadUrl(textFile, process);
  },
  
  selectmenu: function(item) 
  {
  	$('Amsterdam').className = '';
  	$('Buenos_Aires').className = '';
  	$('Kabul').className = '';
  	$('Nairobi').className = '';
  	$('Skopje').className = '';
  	$('Tbilisi').className = '';
  	$('Ankara').className = '';
  	$('Canberra').className = '';
  	$('London').className = '';
  	$('Parisi').className = '';
  	$('Sofia').className = '';
  	$('Wien').className = '';
  	$('Beijing').className = '';
  	$('Habana').className = '';
  	$('Lusaka').className = '';
  	$('Praha').className = '';
  	$('Stockholm').className = '';
  	$('Zgreb').className = '';
  	$('Berlin').className = '';
  	$('Helsinki').className = '';
  	$('Luxembourg').className = '';
  	$('Quito').className = '';
  	$('Tokyo').className = '';
  	$('Bruxelles').className = '';
  	$('Johannesburg').className = '';
  	$('Moskovo').className = '';
  	$('Singapore').className = '';
  	$('Tunis').className = '';
  
  	$('divAmsterdam').style.display = 'none';
  	$('divBuenos_Aires').style.display = 'none';
  	$('divKabul').style.display = 'none';
  	$('divNairobi').style.display = 'none';
  	$('divSkopje').style.display = 'none';
  	$('divTbilisi').style.display = 'none';
  	$('divAnkara').style.display = 'none';
  	$('divCanberra').style.display = 'none';
  	$('divLondon').style.display = 'none';
  	$('divParisi').style.display = 'none';
  	$('divSofia').style.display = 'none';
  	$('divWien').style.display = 'none';
  	$('divBeijing').style.display = 'none';
  	$('divHabana').style.display = 'none';
  	$('divLusaka').style.display = 'none';
  	$('divPraha').style.display = 'none';
  	$('divStockholm').style.display = 'none';
  	$('divZgreb').style.display = 'none';
  	$('divBerlin').style.display = 'none';
  	$('divHelsinki').style.display = 'none';
  	$('divLuxembourg').style.display = 'none';
  	$('divQuito').style.display = 'none';
  	$('divTokyo').style.display = 'none';
  	$('divBruxelles').style.display = 'none';
  	$('divJohannesburg').style.display = 'none';
  	$('divMoskovo').style.display = 'none';
  	$('divSingapore').style.display = 'none';
  	$('divTunis').style.display = 'none';
  
  	$(item).className = 'selected';
  	$('div' + item).style.display = 'block';
  },
  
  initGMap: function()
  {
    if (typeof GMap2 != 'undefined') 
    {
      /**
   * 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, save}
   */
      GMap2.prototype.showBounds = function(bounds_, opt_options)
      {
        var opts = opt_options ||
        {};
        opts.top = opt_options.top * 1 || 0;
        opts.left = opt_options.left * 1 || 0;
        opts.bottom = opt_options.bottom * 1 || 0;
        opts.right = opt_options.right * 1 || 0;
        opts.save = opt_options.save || true;
        opts.disableSetCenter = opt_options.disableSetCenter || false;
        var ty = this.getCurrentMapType();
        var port = this.getSize();
        
        if (!opts.disableSetCenter) 
        {
          var virtualPort = new GSize(port.width - opts.left - opts.right, port.height - opts.top - opts.bottom);
          this.setZoom(ty.getBoundsZoomLevel(bounds_, virtualPort));
          var xOffs = (opts.left - opts.right) / 2;
          var yOffs = (opts.top - opts.bottom) / 2;
          var bPxCenter = this.fromLatLngToDivPixel(bounds_.getCenter());
          var newCenter = this.fromDivPixelToLatLng(new GPoint(bPxCenter.x - xOffs, bPxCenter.y - yOffs));
          this.setCenter(newCenter);
          
          if (opts.save) 
          {
            this.savePosition();
          }
        }
        
        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;
      };
      
      GMap2.prototype.populate = function(points, options)
      {
        var opts = options ||
        {};
        var noCat = true;
        if (opts.cat || opts.iCat) 
        {
          noCat = false;
        }
        
        var catName = opts.cat || "";
        var bar = opts.sidebar;
        var myCat;
        var newCats = [];
        for (var i = 0; i < points.length; i++) 
        {
          if (opts.iCat) 
          { // category from file contents
            catName = points[i].textArray[opts.iCat];
          }
          var theIcon = opts.icon || CAT_ICONS[catName] || CAT_ICONS["DEFAULT_ICON"];
          if (!bar.cats[catName] && !noCat) 
          { // create a category if not found
            myCat = new BarCategory(bar, catName, {
              icon: theIcon
            });
            newCats.push(myCat);
          }
          var iLabel = opts.iLabel || 2;
          var label = points[i].textArray[iLabel];
          points[i].marker = new GMarker(points[i], {
            title: label,
            icon: theIcon
          });
          this.addOverlay(points[i].marker);
          bounds.extend(points[i]); // this must be considered
          createInfoWindow(points[i], opts);
          if (noCat) 
          {
            bar.addEntry(points[i], opts);
          }
          else 
          {
            myCat.addEntry(points[i], opts);
          }
        }
        myCat.check.checked = opts.checked || false;
        myCat.update();
        
        for (i = 0; i < newCats.length; i++) 
        {
          newCats[i].check.checked = opts.checked || false;
          newCats[i].update();
        }
        
        var paddings = {
          top: 30,
          right: 10,
          bottom: 10,
          left: 50
        };
        
        this.showBounds(bounds, paddings);
      };      
    }
  },
  
  showCurrentDate: function()
  {
    var date = new Date();  
    var day = date.getDay();
    var month = date.getMonth();
    var year = date.getFullYear();
    
    $('today-date').innerHTML = date.toLocaleDateString();
  },
  
  showUTCTime: function()
  {
    var curDateTime = new Date();
    var curHour = curDateTime.getHours() + curDateTime.getTimezoneOffset() / 60;
    
    if (curHour > 24) 
    {
      curHour -= 24;
    }
    
    if (curHour < 0) 
    {
      curHour += 24;
    }
    
    var curMin = curDateTime.getMinutes();
    var curTime = ((curHour < 10) ? "0" : "") + curHour + ":" + ((curMin < 10) ? "0" : "") + curMin;
    
    $('utc_time_placeholder').innerHTML = curTime + " UTC";
  },
  
  showLocalTime: function()
  {
    var curDateTime = new Date();
    var curHour = curDateTime.getHours();
    var curMin = curDateTime.getMinutes();
    var curSec = curDateTime.getSeconds();
    var curTime = ((curHour < 10) ? "0" : "") + curHour + ":" + ((curMin < 10) ? "0" : "") + curMin;
      
    $('local_time_placeholder').innerHTML = 'Your time: ' + curTime;
  },
  
  updateTime: function()
  {
    Main.showUTCTime();
    Main.showLocalTime();
  },
  
  setupTimeUpdate: function()
  {
    // Actualizamos cada 1 segundo
    setInterval( this.updateTime, 1000);  
  },
  
  init: function()
  {
    this.initGMap();
   
    this.showCurrentDate(); 
    this.updateTime();
    this.setupTimeUpdate();
    
    //Preload loop
    //Electronics freaks  know the numbering scheme
    var icons = ["black","brown","red","orange","yellow","green","blue","purple","gray","white"];
    for(var color in icons)
    {
      this.tinyImage( icons[color], true);
    }
  
    /**
     * Map
     */
    _mPreferMetric = true;
                           
    //to make size sure for IE too
    var map = new GMap2($("map"), {size: new GSize( 600,400)});
    map.setCenter( new GLatLng( 0,0), 9);
    map.addControl( new GLargeMapControl());
    map.addControl( new GMapTypeControl());
    map.addControl( new GScaleControl());
    map.openInfoWindowHtml( map.getCenter(),"Nice to see you.");
    map.closeInfoWindow(); //preloading infowindow
  
    /**
     * Create the markers, with  infowindow.
     * Create sidebar categories and entries.
     */
    var bounds = new GLatLngBounds();
  
    /**
     * This function triggers the downloading and parsing of a selected text file
     * marker, sidebar and infowindow data is extracted from the file
     */  
    var myBar = new SideBar( $("sidebar"));
  
    var CAT_ICONS = [];
    CAT_ICONS["All stations"] = tinyIcon("green");
    CAT_ICONS["Official wmo stations"] = tinyIcon("blue");
    CAT_ICONS["Private stations"] = tinyIcon("yellow");
    CAT_ICONS["Ski resorts"] = tinyIcon("purple");
    
    this.ajaxLoad( 'all.txt', {cat: 'All stations'});
    this.ajaxLoad( 'wmo.txt', {cat: 'Official wmo stations'});
    this.ajaxLoad( 'private.txt', {cat: 'Private stations'});
    this.ajaxLoad( 'ski.txt', {cat: 'Ski resorts'});  
  },
  
  unload: function()
  {
    if (typeof GUnload != 'undefined') 
    {
      GUnload();
    }
  }
};

/**
 * sidebar with categories
 * @author Esa 2008
 */ 
function SideBar(block_element, opt_options)
{
  var opts = opt_options||{};
  this.division = Main.createElem( 'sidebar-contents');
  block_element.appendChild( this.division);
  this.show = function(){this.division.style.display = 'block';};
  this.hide = function(){this.division.style.display = 'none';};
  this.cats = [];
}

SideBar.prototype =
{
  addEntry: function(point,opt_options)
  {
    var opts = opt_options||{};
    var iLabel = opts.iLabel||2;
    var label = Main.createElem("sidebar-entry", point.textArray[iLabel], "a");
    label.href = "#";
    label.style.display = "block";
    label.onclick = function(){GEvent.trigger(point.marker,'click'); return false;};
    label.onfocus = function(){GEvent.trigger(point.marker,'click'); return false;};
    this.division.appendChild(label);
    
    GEvent.addListener(point.marker,'click',function(){label.focus(); return false;});
  },
  
  clear: function()
  {
    while (this.division.firstChild) 
    {
      this.division.removeChild(this.division.firstChild);
    }
  }  
};

/**
 * category to a sidebar
 * @author Esa 2008
 */ 
function BarCategory(sideBar, catName, opt_options)
{
  var me = this;
  var opts = opt_options||{};
  me.division = Main.createElem("sidebar-cat");
  var cssClasses = "sidebar-cat-header cat-header-"+catName;
  var cat = Main.createElem(cssClasses);
  me.pin = Main.createElem("sidebar-cat-image",null,"img");
  me.pin.src = opts.icon.image;
  cat.appendChild(me.pin);
  var check = Main.createElem("sidebar-cat-check",null,"input");
  me.header = cat;
  check.type = "checkbox";
  check.checked = opts.checked||false;
  cat.appendChild(check);
  var checkLabel = Main.createElem("sidebar-cat-label",catName,"span");
  cat.appendChild(checkLabel);
  
  sideBar.division.appendChild(cat);
  sideBar.division.appendChild(me.division);
  sideBar.cats[catName] = me;
  me.markers = [];
  
  check.onclick = update;
  me.check = check;
}

BarCategory.prototype = 
{
  show: function()
  {
    this.division.style.display = "block";
    this.pin.style.visibility = "visible";
  },
  
  hide: function()
  {
    this.division.style.display = "none";
    this.pin.style.visibility = "hidden";
  },
  
  hilight: function()
  {
    this.header.className = cssClasses +"  hilight-cat-header";
  },
  
  lolight: function()
  {
    this.header.className = cssClasses;
  },
  
  showMarkers: function()
  {
    for (var i = 0; i < me.markers.length; i++)
    {
      this.markers[i].show();
    }
  },
  
  hideMarkers: function()
  {
    for (var i = 0; i < me.markers.length; i++)
    {
      this.markers[i].hide();
      this.markers[i].closeInfoWindow();
    }
  },
  
  update: function()
  {
    if(check.checked)
    {
      this.show();
      this.showMarkers();
      this.hilight();
    }
    else
    {
      this.hide();
      this.hideMarkers();
      this.lolight();
    }
  }
};

/**
 * parseCsv()
 * @return an array of GLatLng() objects
 * @param opt_options object {lat, lng} integers defining the csv cells of coordinates (default: {lat:1, lng:0})
 * @author Esa 2008
 */
String.prototype.parseCsv = function(opt_options)
{
  var results = [];
  var opts = opt_options||{};
  var iLat = opts.lat||1;
  var iLng = opts.lng||0;
  var lines = this.split("\n");
  for (var i=0; i<lines.length; i++) {
    var blocks = lines[i].split('"');
    //finding commas inside quotes. Replace them with '::::'
    for(var j=0;j<blocks.length;j++){
      if(j%2){
        blocks[j]=blocks[j].replace(/,/g,'::::');
      }
    }  //@author Esa 2008, keep this note.
    lines[i] = blocks.join("");
    var lineArray = lines[i].split(",");
    var lat = parseFloat(lineArray[iLat]);
    var lng = parseFloat(lineArray[iLng]);
    var point = new GLatLng(lat,lng);
    //after splitting by commas, we put hidden ones back
    for(var cell in lineArray){
      lineArray[cell] = lineArray[cell].replace(/::::/g,',');
    } //corrupted line step-over
    if(!isNaN(lat+lng)){
      point.textArray = lineArray;
      results.push(point);
    }
  }
  
  return results;
};

EventManager.registerOnLoad( Main.init, Main);
EventManager.registerOnUnload( Main.unload, Main);
