// (c) Geotrips.eu
// If you want to reuse this api, please contact us at webmaster@geotrips.eu

// MediaRSS.

PicasaRss.MRSS_NS  = "http://search.yahoo.com/mrss/";
PicasaRss.MRSS_CONTENT = "content";

PicasaRss.MRSS_THUMBNAIL_NS  = "http://search.yahoo.com/mrss/";
PicasaRss.MRSS_THUMBNAIL_TAG = "thumbnail";
PicasaRss.MRSS_FULL_IMAGE = "content";

PicasaRss.MRSS_VIDEO = "content";

PicasaRss.MRSS_KEYWORDS_NS = PicasaRss.MRSS_THUMBNAIL_NS;
PicasaRss.MRSS_KEYWORDS_TAG = "keywords";

PicasaRss.GML_POS_NS = "http://www.opengis.net/gml";
PicasaRss.GML_POS_TAG= "pos";

// iTunes.
PicasaRss.ITMS_THUMBNAIL_TAG = "coverArt";
PicasaRss.ITMS_THUMBNAIL_NS  = "http://phobos.apple.com/rss/1.0/modules/itms/";

PicasaRss.THUMBNAILS_SMALL = "small";
PicasaRss.THUMBNAILS_MEDIUM = "medium";
PicasaRss.THUMBNAILS_LARGE = "large";

PicasaRss.PIC_SIZE = "576";


function GeoPoint(lat, lon) {
	this.lat = lat;
	this.lon = lon;
}

function Photo(id, thumbUrl, imgUrl, description, point) {
	this.id = id;
	this.thumbUrl = thumbUrl;
	this.imgUrl = imgUrl;
	this.description = description;
        this.fullPrev = false; // noe we load higher resolution of pictures via ajax
	if (point) {
		this.point = point;
	} else { 
		this.point = null;
	}
}


function PicasaRss(photoFeed, options) {
	this.parseOptions(options);
	
	this.photos = [];
	this.cover = null;
	
	this.feedUrl = photoFeed;	
	this.feed = new google.feeds.Feed(this.feedUrl);
	this.feed.setResultFormat(google.feeds.Feed.MIXED_FORMAT);
	this.feed.setNumEntries(this.options.numResults);
	this.feed.load(this.bind(this.feedLoaded));
	
}


/**
 * Setup default option map and apply overrides from constructor.
 * @param {Object} options Options map.
 * @private
 */
PicasaRss.prototype.parseOptions = function(options) {
  var maxEntries;
  if (google != undefined && google.feeds != undefined) {
    maxEntries = google.feeds.Feed.MAX_ENTRIES;
  } else {
    maxEntries = 20;
  }
  // Default Options
  this.options = {
    numResults : maxEntries,
    scaleImages : false,
    
    //Tags and namespaces
    contentTag : PicasaRss.MRSS_CONTENT, 
    thumbnailTag : PicasaRss.MRSS_THUMBNAIL_TAG,
    thumbnailNamespace : PicasaRss.MRSS_THUMBNAIL_NS,
    thumbnailSize : PicasaRss.THUMBNAILS_LARGE,
    keywordNamespace: PicasaRss.MRSS_KEYWORDS_NS,
    keywordTag: PicasaRss.MRSS_KEYWORDS_TAG,
    georssPositionNamespace : PicasaRss.GML_POS_NS,
    georssPositionTag : PicasaRss.GML_POS_TAG,
    videoTag : PicasaRss.MRSS_VIDEO,
    picSize : PicasaRss.PIC_SIZE,
    
    feedLoadCallback : null,
    feedProcessedCallback : null,
    imageClickCallback : null    
  };

  if (options) {
    for (o in this.options) {
      if (typeof options[o] != "undefined") {
        this.options[o] = options[o];
      }
    }
  }
};


	
PicasaRss.prototype.processEntries = function(entries) {
	  for (var i = 0; i < entries.length; i++) {
		entry = entries[i];  
	    var thumbUrl = this.getThumbUrl(entry);	    
	    var imgUrl = this.getImgUrl(entry);
	    var imgFullUrl = this.getImgFullUrl(entry);
	    var description = entry.title;
	    var caption = getXmlNode(entry, "", "description"); //TODO config 
	    if (caption && caption.childNodes.length > 0) {
	    	description = caption.childNodes[0].nodeValue;
	    }
	    
	    var id = 'photo_' + i;	    	    
	    if (thumbUrl && imgUrl) {
	    	
	    	var point = this.getPoint(entry);// optional fields
	    	var photo = new Photo(id, thumbUrl, imgUrl, description, point);
	    	photo.imgFullUrl = imgFullUrl; // optional fields	    	
	    	var intMedia = this.getInternalMedia(entry, photo); //passing context photo - we can reuse already parsed info
	    	var extMedia = this.getExternalMedia(entry, photo);  //assigned via tags
	    	var media = join_asoc(intMedia, extMedia);    		    	
	    	photo.media = media;
	    	photo.specificMapIcon = this.getSpecificMapIcon(entry, photo);
	    	this.photos.push(photo);
	    }
	  }	
	  //alert('Entries processed: ' + this.entries.length);
};

function pausecomp(millis)
{
var date = new Date();
var curDate = null;

do { curDate = new Date(); }
while(curDate-date < millis);
}

PicasaRss.prototype.feedLoaded = function(result) {
 	 // Process the cover
	//TODO
	this.cover = null;

        if (result.error) {
            //TODO: avoid loop
            // alert("ERROR: " + result.error.code + ":" + result.error.message + "Nahravam rozsahlejsiho pruvodce." + "\nStisknete OK a pokracujte prosím pomocí tlacitka aktualizovat nebo F5." );
            alert("Nahravam rozsahlejsiho pruvodce." + "\nStisknete OK a pokracujte prosím pomocí tlacitka aktualizovat nebo F5." );
            //this.feed.load(this.bind(this.feedLoaded));
            return;
        }
	 // Process the entries.
	var entries = result.feed.entries;
	this.processEntries(entries);
	
	this.photos.coverDescription = result.feed.description;
	
	if (this.options.feedProcessedCallback) {
	    this.options.feedProcessedCallback(this.photos, this.cover);
	}
}

PicasaRss.prototype.getPoint = function(entry) {
	var point = getXmlNode(entry,
			this.options.georssPositionNamespace,
			this.options.georssPositionTag);
	if (point) {
		//TODO: configurable
		var value = point.childNodes[0].nodeValue;
		if (value) {
			var pos = value.split(' ');
			if (pos.length == 2) {
				var geoPoint = new GeoPoint(pos[0], pos[1]);
				return geoPoint;
			}
		}
	}
	return null;
}




// Return first xml node or null
function getXmlNode(entry, ns, tag) {
	var nodes = null;
	nodes = google.feeds.getElementsByTagNameNS(
			entry.xmlNode, ns, tag);
	if (nodes && nodes.length > 0) {
		return nodes[0]; 
	}
	return null;
}


function getXmlNodes(entry, ns, tag) {
	var nodes = null;
	nodes = google.feeds.getElementsByTagNameNS(
			entry.xmlNode, ns, tag);	
	return nodes;
}

PicasaRss.prototype.getThumbUrl = function(entry) {
	// TODO: lazy
	var thumbUrl = getXmlNode(entry, 
			this.options.thumbnailNamespace, 
			this.options.thumbnailTag);
				
	if (thumbUrl) {		
		thumbUrl = thumbUrl.getAttribute("url").replace(/\/[^\/]+\/([^\/]+$)/, '/s72/$1');;
	}
	return thumbUrl;
}

PicasaRss.prototype.getImgUrl = function(entry) {
	 //Picasa has 72, 144, 200, 320, 400, 576, 640, 720, 800, 1024, 1152, 1280, 1440, 1600.
	 var photoUrl = null;            
         photoUrl = this.getThumbUrl(entry).replace(/\/[^\/]+\/([^\/]+$)/, '/s576/$1');
         photoUrl = this.getThumbUrl(entry).replace(/\/[^\/]+\/([^\/]+$)/, '/s' + this.options.picSize + '/$1');
         //photoUrl = this.getThumbUrl(entry).replace(/\/(d|s72)\//, '/s576/');
         //photoUrl = this.getThumbUrl(entry).replace('/s72/', '/s576/');
	 return photoUrl;
}

PicasaRss.prototype.getImgFullUrl = function(entry) {
	 //Picasa has 72, 144, 200, 320, 400, 576, 640, 720, 800, 1024, 1152, 1280, 1440, 1600.
	 var photoUrl = null;
	 //photoUrl = this.getThumbUrl(entry).replace('s72', 'd');
          photoUrl = this.getThumbUrl(entry).replace(/\/[^\/]+\/([^\/]+$)/, '/d/$1');
	 return photoUrl;
}
//GEOTRIPS Specific stuff && enhanced to get specific map icon type like hotel
PicasaRss.prototype.getSpecificMapIcon = function(entry, photo) {
	// Determine which media are assigned to photo by keywords
	var specificMapIcon = null;

	var keyWords = getXmlNode(entry,
			this.options.keywordNamespace,
			this.options.keywordTag);

	if (keyWords && keyWords.childNodes[0]) {
		//TODO: configurable
		var value = keyWords.childNodes[0].nodeValue;
		if (value) {
			var kw = value.split(', ');
			for (k in kw) {
				//TODO: configurable chain of processors
				var m = new SpecificMapIcon(kw[k], photo); //passing context with image url ...
				//....
				if (m.value) {					
					specificMapIcon = m;
                                        break;
				}
				

			}
		}
	}
	return specificMapIcon;
}

//GEOTRIPS Specific stuff && enhanced to get specific map icon type like hotel
PicasaRss.prototype.getExternalMedia = function(entry, photo) {
	// Determine which media are assigned to photo by keywords
	var media = [];
	
	var keyWords = getXmlNode(entry, 
			this.options.keywordNamespace, 
			this.options.keywordTag);
	
	if (keyWords && keyWords.childNodes[0]) {
		//TODO: configurable
		var value = keyWords.childNodes[0].nodeValue;
		if (value) {
			var kw = value.split(', ');
			for (k in kw) {
				//TODO: configurable chain of processors
				var m = new PanoramaInternal(kw[k], photo); //passing context with image url ...
				//....
				if (m.value) {
					//alert(m.xfov + ',' + m.yfov);
					media[m.type] = m;
					break;  
				}
				m = new YoutubeVideo(kw[k], photo); //passing context with image url ...
				//....
				if (m.value) {
					//alert(m.xfov + ',' + m.yfov);
					media[m.type] = m;
					break;
				}

                                m = new MediaPlayerVideo(kw[k], photo); //passing context with image url ...
				//....
				if (m.value) {
					//alert(m.xfov + ',' + m.yfov);
					media[m.type] = m;
					break;
				}
                               
			}
		}
	}
	return media;
}

PicasaRss.prototype.getInternalMedia = function(entry, photo) {
	var media = [];
	var content = getXmlNodes(entry, 
			PicasaRss.MRSS_NS, //TODO
			this.options.contentTag);	
	
	for (var i = 0; i < content.length; i++) {
		var xmlNode = content[i];

		var m = new PicasaFlashVideo(xmlNode, photo);			
	
		//...
	
		if (m.value) {
			//alert(m.xfov + ',' + m.yfov);
			media[m.type] = m;
			break;
		}						
		
	}
	return media;
	
}

/**
 * Helper method to bind this instance correctly.
 * @param {Object} method function/method to bind.
 * @return {Function}
 * @private
 */
PicasaRss.prototype.bind = function(method) {
  var self = this;
  var opt_args = [].slice.call(arguments, 1);
  return function() {
    var args = opt_args.concat([].slice.call(arguments));
    return method.apply(self, args);
  }
};




	
	
	
	
	
	
	
	
	

