// Mark the HTML so we can distinguish local from web display
setTimeout(function()
{
  if (window.location.href.match("vista"))
  {
    document.body.className = "isLocal";
  }
}, 0);


var utils =
{
  showFlickr : function(button, count)
  {
    if (button)
    {
      // We disable the button, since no need to use it twice
      button.disabled = true;
    }

    var element = button;

    var links = findLinks(button, count);

    // Find the id in links to flickr etc
    var flickrIds = [];
    var picasaIds = [];
    var panoramioIds = [];
    var smugmugIds = [];

    // The links array is "live", so we can't do anything to add links on the first pass
    for (var i = 0; i < links.length; i++)
    {
      var link = links[i].href;

      if (link)
      {
        if (link.match(/flickr.com/))
        {
          var id = link.split("/").pop();

          // Add this to the queue of work
          flickrIds.push(id);

          // Make sure we know where to put the result
          links[i].setAttribute("id", "id" + id);
        }
        else if (link.match(/picasaweb/))
        {
          // Add this to the queue of work - we need the whole link
          picasaIds.push(link);

          var id = link.split("#").pop();

          // Make sure we know where to put the result
          links[i].setAttribute("id", "id" + id);
        }
        else if (link.match(/panoramio/))
        {
          // Add this to the queue of work - we need the whole link
          panoramioIds.push(link);

          var id = link.split("/").pop();

          links[i].setAttribute("id", "id" + id);
        }
        else if (link.match(/smugmug/))
        {
          // Add this to the queue of work - we need the whole link
          smugmugIds.push(link);

          var id = link.split("/").pop().split("#")[1];

          links[i].setAttribute("id", "id" + id);
        }
      }
    }

    // Now process the ids
    // First any from Flickr
    for (var i = 0; i < flickrIds.length; i++)
    {
      var id = flickrIds[i];

      var photo = getFlickrData(id);
      if (photo)
      {
        processPhotoData(photo);
      }
      else
      {
        // Not yet fetched this data
        dynamicCall("flickr.photos.getInfo", id);
      }
    }
    // Now any from PicasaWeb
    for (var i = 0; i < picasaIds.length; i++)
    {
      var urlParts = picasaIds[i].split("/");

      // Extract the bits of the url
      var idAndAlbum = urlParts.pop().split("#");
      var id = idAndAlbum.pop();
      var album = idAndAlbum.pop();
      var user = urlParts.pop();

      // @@@ should cache this data...

      dynamicScript("http://picasaweb.google.com/data/feed/api/user/" + user + "/album/" + album + "/photoid/" + id +
                    "?kind=comment&alt=json&callback=picasaCallback" +
                    "&thumbsize=320");
    }
    // Now any from Panoramio
    for (var i = 0; i < panoramioIds.length; i++)
    {
      processPanoramioLink(panoramioIds[i]);
    }
    // Now any from SmugMug
    for (var i = 0; i < smugmugIds.length; i++)
    {
      processSmugmugLink(smugmugIds[i]);
    }

    function dynamicCall(method, id, fragment)
    {
      var url = "http://api.flickr.com/services/rest/?method=" + method + "&format=json" +
                (id != null ? ("&photo_id=" + id) : "") +
                "&api_key=" + apikey() +
                (fragment ? fragment : "");

      dynamicScript(url);
    }



    function findLinks(element, count)
    {
      var links = [];
      if (element && count)
      {
        // We know where the elements are, so just process those few links
        element = element.parentNode.getElementsByTagName("div")[0];
      }
      else
      {
        // Consider all the links on the page
        element = document;
      }

      var links = element.getElementsByTagName("a");

      return links;
    }
  }

}

    function apikey()
    {
      return "c67a275298ce0ff70afda10fe71d50b2";
    }

    function dynamicScript(scriptUrl)
    {
      var scriptsHere = document.getElementsByTagName("body")[0];

      var oScript = document.createElement('script');
      oScript.src = scriptUrl;
      oScript.type = 'text/javascript';
      scriptsHere.appendChild(oScript);
    }


function jsonFlickrApi(data)
{
  var photo = data.photo;
  if (photo)
  {
    processPhotoData(photo);

    storePhotoData(photo);
  }
}

function processPhotoData(photo)
{
  var image = "http://farm" + photo.farm + ".static.flickr.com/" + photo.server + "/" + photo.id + "_" + photo.secret + "_m.jpg";
  var page = "http://www.flickr.com/photos/" + photo.owner.nsid + "/" + photo.id;
  var title = photo.title._content + " by " + photo.owner.username + " on " + photo.dates.taken;
  var caption = photo.title._content + " [" + photo.dates.taken.split(" ")[0] + "]" +
                "<br/>&copy; <a href='http://www.flickr.com/photos/" + photo.owner.nsid + "/'>" + photo.owner.username + "</a>";
  if (photo.location)
  {
    var latitude = photo.location.latitude;
    var longitude = photo.location.longitude;
  }

  insertPhoto(photo.id,
              image,
              page,
              title,
              caption,
              "flickrImage",
              latitude, longitude);
}

function insertPhoto(id,
                     image,
                     page,
                     title,
                     caption,
                     class_,
                     latitude,
                     longitude)
{
  // To help with identifying unknown photos, we add the id to the caption on the unidentified page
  if (location.href.indexOf("unidentified") >= 0)
  {
    caption = id + "<br/>" + caption;
  }

  var element = document.createElement("div");
  element.className = class_;
  element.innerHTML = "<a href='" + page + "'><img src='" + image + "' title='" + title + "'/></a>" +
                      "<div class='flickrcaption'>" + caption + "</div>" +
                      (latitude ? "<a class='geo' href='http://data.mapchannels.com/mm/dual2/map.htm?x=" + longitude +
                                     "&y=" + latitude + "&z=19&xb=" + longitude + "&yb=" + latitude + "&bar=1&mw=1&gm=1&ve=3&sv=0&svb=0'>geo</a>" : "");

  var place = document.getElementById("id" + id);
  place.parentNode.replaceChild(element, place);
}

function useMap()
{
  var h = document.location.href;
  var key =
    h.match(/windmillworld.com/) ? "ABQIAAAAl_QCOunNvqx-OwhB0NkkMBShv59ULttBIE1f04TJ1FCtoj4Z3xTTx5vvGIhsR6DZVi19wZHTAyU9ag" :
    h.match(/:\/\/mega/)         ? "ABQIAAAAV-8iOqJCwCjGH7_aWWLxtRSXnVbNNUQH2EJ8VsW4F8RgyqPwUxSe0tr_Qi1XmN4nIOcSGyC99hdWfw" :
    h.match(/:\/\/vista/)        ? "ABQIAAAAl_QCOunNvqx-OwhB0NkkMBT2TXx1qgjJWGmoOIXUffWj9uOcoBTZDtAM_bOHrRLpQzc7udWVvIgZ8w" :
                                   "ABQIAAAAl_QCOunNvqx-OwhB0NkkMBT2yXp_ZAY8_ufC3CFXhHIE1NvwkxTUyCfOf14vzJ5XtzfNrWLqv5U4wg";
  document.write('<script src="http://maps.google.com/maps?file=api&v=2.x&key=' + key + '"></script>');
}

function resizeMap(factor, id)
{
  var map = document.getElementById(id || 'map');

  var centre = map.googleMap.getCenter();

  var height = map.style.height;
  map.style.height = Math.floor(height.substring(0, height.length - 2) * factor) + "px";
  var width = map.style.width;
  map.style.width = Math.floor(width.substring(0, width.length - 2) * factor) + "px";

  // Tell the map object that the size changed
  map.googleMap.checkResize();

  // Recentre on where we were before
  map.googleMap.setCenter(centre);

  return false;
}

function showMap(longitude, latitude, id)
{
  var map = document.getElementById(id || 'map');

  map.style.height = "350px";
  map.style.width = "525px";

  var googleMap = new GMap(map);
  googleMap.addControl(new GSmallMapControl());
  googleMap.addControl(new GMapTypeControl());
  googleMap.addControl(new GScaleControl());  // not documented in the API pages

  googleMap.addMapType(G_SATELLITE_3D_MAP);

  googleMap.centerAndZoom(new GPoint(longitude,  latitude), 1);
  googleMap.setMapType(G_HYBRID_MAP);

  // Save the map object, so we can access it later
  map.googleMap = googleMap;
}


var db;

function getFlickrData(id)
{
  if (window.google && google.gears)
  {
    var fields = [
      "farm",
      "server",
      "secret",
      "title",
      "owner_nsid",
      "owner_username",
      "dates_taken"
    ];

    // Google gears is installed - we can use that for persistent storage
    if (!db)
    {
      // We have not accessed the database yet
      try
      {
        // db is a global variable
        db = google.gears.factory.create('beta.database', '1.0');

        try
        {
          db.open('flickr');

          db.execute('create table if not exists Photos (id text unique, ' + fields.join(" text, ") + ')');
        }
        catch (e)
        {
          alertException("Problem opening database:", e);
        }
      }
      catch (ex)
      {
        alertException("Problem creating database:", ex);
      }
    }

    if (db)
    {
      var rs = db.execute('select ' + fields.join(",") + ' from Photos where id=?', [id]);
      if (rs.isValidRow())
      {
        var photo = {
          id : id,
          farm : rs.fieldByName("farm"),
          server : rs.fieldByName("server"),
          secret : rs.fieldByName("secret"),
          title : {
            _content : rs.fieldByName("title")
          },
          owner : {
            nsid : rs.fieldByName("owner_nsid"),
            username : rs.fieldByName("owner_username")
          },
          dates : {
            taken : rs.fieldByName("dates_taken")
          }
        }
      }
    }
  }

  return photo;
}

function storePhotoData(photo)
{
  if (db)
  {
    // We are storing the data
    try
    {
      var rs = db.execute('replace into Photos values (?, ?, ?, ?, ?, ?, ?, ?)',
                          [photo.id, photo.farm, photo.server, photo.secret, photo.title._content, photo.owner.nsid, photo.owner.username, photo.dates.taken]);
    }
    catch (e)
    {
      alert(e);
    }
  }
}


function alertException(message, e)
{
  var msg = e.message || ("" + e);

  alert(message + " " + msg);
}

function picasaCallback(data)
{
  var item = data.feed;

  var id = item.gphoto$id.$t;
  var image = item.media$group.media$thumbnail[0].url;
  var page = item.link[1].href;

  var dateTaken = item.gphoto$timestamp ? (new Date(parseInt(item.gphoto$timestamp.$t))).toLocaleString() : "";

  // A search feed has a summary, but this photo feed has a subtitle.
  //var caption = item.summary.$t;
  // There is no info on the author given

  var author = item.link[0].href.substring(item.link[0].href.indexOf("user")).split("/")[1];

  var title = item.subtitle.$t + " by " + author;
  var caption = item.subtitle.$t;
  if (dateTaken)
  {
    title += " on " + dateTaken;

    caption += " [" + dateTaken.split(" ").slice(0, 3).join(" ") + "]";
  }
  caption += "<br/>&copy; <a href='http://picasaweb.google.com/" + author + "'>" + author + "</a>";

  insertPhoto(id,
              image,
              page,
              title,
              caption,
              "picasaImage");
}

function processSmugmugLink(link)
{
  var bits = link.split("/");
  var file = bits.pop();

  var id = file.split("#")[1];

  var author = bits[2].split(".")[0];

  var title = "Photo by " + author;

  var caption = "&copy; <a href='http://" + author + ".smugmug.com/'>" + author + "</a>";

  var image = "http://" + author + ".smugmug.com/photos/" + id + "-S.jpg";

  insertPhoto(id,
              image,
              link,
              title,
              caption,
              "smugmugImage");
}

function processPanoramioLink(link)
{
  var bits = link.split("/");

  var id = bits.pop();

  var author = "";

  var title = "Photo by Panoramio member";

  var caption = "Image " + id;

  var image = "http://static2.bareka.com/photos/small/" + id + ".jpg";

  insertPhoto(id,
              image,
              link,
              title,
              caption,
              "panoramioImage");
}


// Renable any disabled buttons
function reenableButtons()
{
  var buttons = document.getElementsByTagName("button");

  for (var i = 0; i < buttons.length; i++)
  {
    buttons[i].removeAttribute("disabled");
  }
}

function addEvent(when, callback)
{
  if (document.addEventListener)
  {
    document.addEventListener(when, callback, true);
  }
  else
  {
    document.attachEvent("on" + when, callback);
  }
}

addEvent("load", reenableButtons);



var uniqueId = 0;

function geoSearch(latitude, longitude, element)
{
  var imageLinks = {};
  var links = document.links;
  for (var i = 0; i < links.length; i++)
  {
    var link = links[i].href;

    //if (imageLinks[link])
    //{
    //  alert("Duplicate link" + link);
    //}
    imageLinks[link] = true;
  }

  element.disabled = true;

  var deltax = 0.003;
  var deltay = 0.006;

  var minx = longitude - deltax;
  var miny = latitude - deltay;
  var maxx = longitude + deltax;
  var maxy = latitude + deltay;

//  var minx = -14.491739;
//  var miny = 28.077509;
//  var maxx = -13.8199901433429;
//  var maxy = 28.7505921529354;

  var accumulatedPanoramio = [];

  var panoramioCallback = "insertPanoramio" + uniqueId++;

  function panoramioBatch()
  {
    var panoramioURL = "http://www.panoramio.com/map/get_panoramas.php?order=popularity&set=full" +
      "&from=" + accumulatedPanoramio.length + "&to=" + (accumulatedPanoramio.length + 100) +
      "&minx=" + minx + "&miny=" + miny + "&maxx=" + maxx + "&maxy=" + maxy +
      "&size=medium&callback=" + panoramioCallback;

    dynamicScript(panoramioURL);
  }

  panoramioBatch();

  var flickrCallback = "insertFlickr" + uniqueId++;
  var flickrURL = "http://api.flickr.com/services/rest/?method=flickr.photos.search" +
                  "&api_key=" + apikey() +
                  "&text=windmill OR mill" +
                  "&lat=" + latitude +
                  "&lon=" + longitude +
                  "&radius=1" +
                  "&extras=date_taken,owner_name" +
                  "&format=json&jsoncallback=" + flickrCallback;

  dynamicScript(flickrURL);

  var picasaCallback = "insertPicasa" + uniqueId++;
  var picasaURL = "http://picasaweb.google.com/data/feed/api/all?kind=photo&alt=json&callback=" + picasaCallback +
                  "&start-index=1" +
                  "&max-results=200" +
                  "&thumbsize=512" +
                  "&orderby=date" +
                  "&q=windmill OR mill" +
                  "&bbox=" + minx + "," + miny + "," + maxx + "," + maxy;
  
  dynamicScript(picasaURL);

  window[flickrCallback] = function(json)
  {
    for (var i = 0; i < json.photos.photo.length; i++)
    {
      var photo = json.photos.photo[i];

      var image = "http://farm" + photo.farm + ".static.flickr.com/" + photo.server + "/" + photo.id + "_" + photo.secret + ".jpg";
      var link  = "http://www.flickr.com/photos/" + photo.owner + "/" + photo.id;
      var ownerLink = "http://www.flickr.com/photos/" + photo.owner;

      var item = 
      {
        id : photo.id,
        image : image,
        link : link,
        title : photo.title,
        owner : ownerLink,
        name : photo.ownername,
        icon : "http://www.flickr.com/favicon.ico",

        extra : " (" + photo.id + " taken " + photo.datetaken + ")"
      };

      addItem("flickr", item);
    }

    if (json.photos.photo.length === 0)
    {
      var div = document.createElement("div");
      div.innerHTML = "No nearby photos found on Flickr";

      element.parentNode.appendChild(div);
    }

    delete window[flickrCallback];
  };

  window[picasaCallback] = function(data)
  {
    var count = data.feed.entry ? data.feed.entry.length : 0;
    for (var i = 0; i < count; i++)
    {
      var entry = data.feed.entry[i];

      // Some bits we use a number of time, so make them named locals
      var ownerLink = entry.author[0].uri.$t;

      // Now we have to form the link ourselves from component parts
      var albumLink = ownerLink + "/" + entry.gphoto$albumctitle.$t + "#";
      var link = albumLink + entry.gphoto$id.$t;

      var item =
      {
        id : entry.gphoto$id.$t,
        image : entry.media$group.media$thumbnail[0].url,
        link : link,
        title : entry.summary.$t || "{untitled}",
        name : entry.author[0].name.$t + " (" + entry.author[0].email.$t + ")",
        owner : ownerLink,
        icon : "http://picasa.google.com/assets/picasa.ico",

        extra : "(" + entry.gphoto$id.$t +
                (entry.gphoto$timestamp ? " taken " + (new Date(parseInt(entry.gphoto$timestamp.$t))).toLocaleString() : "") +
                "<div>Album:<a href='" + albumLink + "'>"+ entry.gphoto$albumtitle.$t + "</a> " +
                entry.gphoto$albumdesc[0].$t + "</div>"
      };

      addItem("picasa", item);
    }

    if (count === 0)
    {
      var div = document.createElement("div");
      div.innerHTML = "No nearby photos found in Picasa Web Albums";

      element.parentNode.appendChild(div);
    }

    delete window[picasaCallback];
  };

  window[panoramioCallback] = function(json)
  {
    if (json.count > accumulatedPanoramio.length + 100)
    {
      // We have more to fetch, so just accumulate this set
      accumulatedPanoramio = accumulatedPanoramio.concat(json.photos);

      // and fetch the next batch
      panoramioBatch();
    }
    else
    {
      json.photos = accumulatedPanoramio.concat(json.photos);

      // Sort the photo by relevance
      for (var i = 0; i < json.photos.length; i++)
      {
        var photo = json.photos[i];

        // Keep the original order for items we can't assign a relevence to
        photo.originalIndex = i;

        var millScore = photo.photo_title.match(/mill|molin|moulin|muhle/i);
        var windScore = photo.photo_title.match(/wind|vent/i);

        function score(matches)
        {
          return matches ? matches.length : 0;
        }
        photo.relevance = score(millScore) * 5 + score(windScore);
      }
      json.photos.sort(function(a,b){
        if (a.relevance == b.relevance)
        {
          return a.originalIndex - b.originalIndex;
        }
        else
        {
          return b.relevance - a.relevance;
        }
      });

      for (var i = 0; i < json.photos.length; i++)
      {
        var photo = json.photos[i];

        var item = 
        {
          id : photo.photo_id,
          image : photo.photo_file_url,
          link : photo.photo_url,
          title : photo.photo_title,
          owner : photo.owner_url,
          name : photo.owner_name,
          icon : "http://www.panoramio.com/img/favicon.ico",

          extra : "(" + photo.photo_id + " uploaded " + photo.upload_date + ")"
          //,debug : photo.relevance + "," + photo.originalIndex
        };

        addItem("pan", item);
      }

      var div = document.createElement("div");
      if (json.photos.length)
      {
        div.innerHTML =
          'Photos provided by <a href="http://www.panoramio.com">Panoramio</a> are under the copyright of their owners.';
      }
      else
      {
        div.innerHTML = "No nearby photos found on Panoramio";
      }

      element.parentNode.appendChild(div);

      delete window[panoramioCallback];

    }
  };

  function addItem(type, item)
  {
    var div = document.createElement("div");
    div.id = type + uniqueId++;

    if (imageLinks[item.link])
    {
      var html = "Ignoring known image " + item.id;
    }
    else
    {
      var html = 
        '<img id="id' + item.id + '" onclick="selectItem(this)" src="' + item.image + '"/> ' +
        '<img src="' + item.icon + '"/>' +
        '<a href="' + item.link + '">' + (item.title || "{untitled}") + "</a> by " +
        '<a href="' + item.owner + '">' + item.name + "</a>" +
        " " + item.extra +
        "<button onclick='hideElement(\"" + div.id + "\")'>Hide</button>";
      if (item.debug)
      {
        html += " [" + item.debug + "]";
      }
    }
    div.innerHTML = html;

    element.parentNode.appendChild(div);
  }
}

function hideElement(id)
{
  document.getElementById(id).style.display = "none";
}

function selectItem(element)
{
  var c = element.className;

  if (c.indexOf("selected") != -1)
  {
    c = c.replace("selected", "");
  }
  else
  {
    c += " selected";
  }
  element.className = c;

  var text = [];
  var container = element.parentNode.parentNode;
  var images = container.getElementsByTagName("img");
  for (var i = 0; i < images.length; i++)
  {
    var image = images[i];
    if (image.className.match("selected"))
    {
      if (image.src.match("flickr.com|ggpht"))
      {
        var link = image.parentNode.getElementsByTagName("a")[0];

        text.push("<id>" + link.getAttribute("href") + "</id>");
      }
      else
      {
        text.push("<id>" + image.id.substring(2) + "</id>");
      }
    }
  }

  function clearAll()
  {
    var images = container.getElementsByTagName("img");
    for (var i = 0; i < images.length; i++)
    {
      var image = images[i];
      if (image.className.match("selected"))
      {
        image.className = image.className.replace("selected","");
        image.style.display = "none";
      }
    }

    ta.value = "";
  }

  var ta = container.getElementsByTagName("textarea");
  if (ta.length)
  {
    ta = ta[0];
  }
  else
  {
    ta = document.createElement("textarea");
    container.appendChild(ta);

    var clearAll = document.createElement("button");
    clearAll.innerHTML = "Clear and hide";
    clearAll.onclick = clearAll;
    container.appendChild(clearAll);
  }

  ta.value = text.join("\n");
  ta.onfocus = function(){selectAllText(ta)};
}


// Functions lifted from Live Clip from Microsoft
function setSelectionRange(input, begin, end)
{
  if (input.setSelectionRange)
  {
    input.focus();
    input.setSelectionRange(begin, end);
  }
  else if (input.createTextRange)
  {
    var range = input.createTextRange();
    range.collapse(true);
    range.moveEnd('character', end);
    range.moveStart('character', begin);
    range.select();
  }
}
function selectAllText(input)
{
  setSelectionRange(input, 0, input.value.length);
}
