    //requires jquery 1.3.2 & jquery.address 1.2.2

    //global variable to access the gallery data externally
    var NG_GalleryData = new Array();

    (function($) {
      $.fn.ng_gallery = function(settings) {
        settings = $.extend({startImage:''},settings);

        return $(this).each(function(i) {
          var data = new Array();
          var gallery = $(this);
                $('.gallery_item_container').html("<div id='gallery_text'></div><div id='next_image'><a href='#'></a><p class='action'><a href='#'>Next »</a></p></div><div class='clear'></div>");
          var galleryText = $('#gallery_text');
          var nextImg = $('#next_image');
          var shareBtns = $('#gallery').parent().find('div.aside');
          var socialBtns = $('.article_body');
          var startIndex = 0;
          var skipURLUpdate = false;
          var formSelected = false;
          var newsletter = $('.newsletter_registration').length > 0 ? $('.newsletter_registration').clone() : null;
          var comments = $(".ng_comments");
          var FADE_TIME = 200;

          NG_GalleryData.push(new Array());

          gallery.find('ul:first > li').each(function(i) {
            var thumb = $(this).find('a.thumb');
            if(thumb.length <= 0) return;
            var alt = thumb.find('img').attr('alt');
            if (typeof gal_link_fix=="undefined" || gal_link_fix==false ) {
                var img = "<img src='"+thumb.attr('href')+"' alt='"+alt+"' />";    
            } else {
                link_val = $(thumb).siblings('div').find('h2 a').attr('href');
                if (typeof link_val!="undefined") var img = "<a href='"+link_val+"'><img src='"+thumb.attr('href')+"' alt='"+alt+"' /></a>";
                else var img = "<img src='"+thumb.attr('href')+"' alt='"+alt+"' />";
            }
            var filenameA = thumb.attr('href').split('/');
            var filename = filenameA[filenameA.length-1];
            thumb.find('img').attr('alt',"");
            if(filename.length <= 0) filename = String(i);
            if(filename == settings.startImage) startIndex = i;
            data.push({
              thumb: thumb.html(),
              img: img,
              url: thumb.attr('href'),
              alt: alt,
              text: $(this).find('div:first').html(),
              filename: filename,
              loaded: false,
              video: $(this).find('.in-gallery-video').text(),
              comment_selector: ".ng_comments.photo-comments-" + i
            });
            NG_GalleryData[0].push({image_url:thumb.attr('href'),text:$(this).find('div:first')[0]});
          });

          var s = new ImageSelector(this,data);

          s.addEventListener("CHANGED",changeImage);
          s.addEventListener("INTERJECTED",interjected);
          gallery.append("<div class='main-image'></div>");

          if(newsletter) {
            var nPos = parseInt(newsletter.attr('data-pos'));
            nPos = nPos > 0 && nPos <= data.length ? nPos : data.length;
            s.setInterjector(nPos);
    	    $('img.newsletter_bg_image').remove();
          }

          nextImg.find('a').click(function(e) {
            s.setSelected(s.getSelected()+1);
            $(document).scrollTop(300);
            e.preventDefault();
          });

          $.address.externalChange(function(e) {
            var filename = $.address.pathNames()[0];

            if(filename == undefined) {
              skipURLUpdate = true;
              s.setSelected(0);
            } else {
              if (filename == "gnl-form") {
                  formSelected = true;
                  s.setSelected(data.length);
              } else {
                  for(var i = 0; i < data.length; i++) {
                      if(data[i].filename == filename) {
                          s.setSelected(i);
                      }
                  }
              }
            }
          });

          function changeImage(target) {
            var selected = data[s.getSelected()];

            //preload the image if not already loaded for quicker percieved response
            if(!selected.loaded) {
              var img = new Image();
              img.src = selected.url;
              selected.loaded = true;
            }
            gallery.find('.main-image').animate({opacity:0},FADE_TIME,function() {
              gallery.find('.main-image').html(selected.img);

              gallery.find('.main-image img').load(function(e){
                gallery.find('.main-image img').attr('alt',selected.alt);
                gallery.find('.main-image').show().css('min-height',gallery.find('.main-image img').height());
              }).click(function(e){
                var sel = s.getSelected();
    	    s.setSelected(sel+1);
              });
              galleryText.html(selected.text);
              if(skipURLUpdate) skipURLUpdate = false;
              else $.address.value(selected.filename);
              shareBtns.show();
              socialBtns.show();
              if(s.getSelected() < data.length-1) {nextImg.find('a:first').html(data[s.getSelected()+1].thumb);nextImg.show();}
              else nextImg.hide();
              $(this).animate({opacity:1},FADE_TIME,function(){ngsPageView();});
            });

            //enables in gallery video view
            gallery.find('.video-action, .video-wrapper, .hide-video').remove();
            gallery.find('.image-selector ul').removeClass('video');
            if(selected.video.length > 0) {
              vidData = selected.video.split(',');
              gallery.find('.image-selector ul').addClass('video');
              gallery.find('.main-image').before('<div class="video-action"></div><div class="hide-video"></div><div class="video-wrapper"><div id="video-holder"></div></div>');
              gallery.find('.video-action').bind('click',function(e) {
                loadVideo('video-holder',vidData[0],vidData[1] || 'singletitlenews',610,343,vidData[2]);
                gallery.find('.video-action').fadeOut(500,function(){gallery.find('.hide-video').fadeIn(500);});
                gallery.find('.main-image').fadeOut(500,function(){gallery.find('.video-wrapper').show(500);});
                e.preventDefault();
              });
              gallery.find('.hide-video').bind('click',function(e) {
                gallery.find('.hide-video').fadeOut(500,function(){gallery.find('.video-action').fadeIn(500);});
                gallery.find('.video-wrapper').fadeOut(500,function(){gallery.find('.main-image').fadeIn(500);gallery.find('.video-wrapper').html('<div id="video-holder"></div>');});
                e.preventDefault();
              });
            }

            // show the proper comments && display newsletter if enabled
            if(comments.length) {
              comments.hide();
              var commentBlock = $(selected.comment_selector);
              var pasTag = commentBlock.find("[plckcommentonkeytype=article]:first");
              articleKey = pasTag.attr("plckcommentonkey");
              getCommentsInfo(articleKey);
              // only show the comments on non-int'l sites
              if(window.location.hostname.endsWith(".com")) commentBlock.show();
            }
          }

          //show newsletter based on the position selected
          function interjected(e) {
            gallery.find('.main-image').html('<div id=\"gnl_form\"></div><div id=\"gnl_thumbs\"></div><div style=\"clear: both;\"></div>');
            $.address.value('gnl-form');
            //Must be cloned as appending it to another div will move it and cause it to be erased when another image is clicked
            $("div.newsletter_registration").clone().appendTo($("div#gnl_form"));
            $("div#gnl_form div.newsletter_registration").show();
            $('#gallery').parent().parent().children('div.thumbnail_grid').clone().appendTo($("div#gnl_thumbs"));
            $("div#gnl_thumbs div.thumbnail_grid").show();
            galleryText.html('');
            nextImg.hide();
            shareBtns.hide();
            socialBtns.hide();
            comments.hide();
            $('form#newsletter_index').submit(function() {return bindNewsletterForm();});
    	    ngsPageView('email_newsletter_registration_gallery_id'+$('input[name|=newsletter]').attr('value'));
          }

          function bindNewsletterForm(){
            // Get the email address.
            var userEmail = $("form#newsletter_index input[name=email]").val();

            // Validate the email address and, if valid, make the call to the backend.
            if (userEmail != "" && validate_email(userEmail) === true) {

              // POST the newsletter registration form to the backend.
              $.ajax({
                type: 'POST',
                url: '/newsletter/ajax/register/',
                data: $('form#newsletter_index').serializeArray(),
                dataType: 'json',
                success: function(response) {
                  if (response.result == 'success') {
                      //success! show 'email has been sent' message
                      $("form#newsletter_index .runner, form#newsletter_index p.input, form#newsletter_index .submitbtn, form#newsletter_index ul,").hide();
                      $("form#newsletter_index .runner").after("<div class='success'>We have sent you an email with a link to confirm and manage your newsletter preferences.</div>");
    		  ngsPageView('email_newsletter_registration_gallery_id'+$('input[name|=newsletter]').attr('value')+'_confirmation');
                  }
                  else if (response.result == 'error') {
                    // Show the form (with error messages)
                    $("form#newsletter_index .runner").hide();
                    $("form#newsletter_index .runner").after("<div class='error'>"+response.result_message+"</div>");
                    setTimeout("$('form#newsletter_index .error').remove();$('form#newsletter_index .runner').fadeIn(1000)", 3000);
                  }
                },
                error: function() {
                  $("form#newsletter_index .runner").hide();
                  $("form#newsletter_index .runner").after("<div class='error'>Please try again later.</div>");
                  setTimeout("$('form#newsletter_index div.error').remove();$('form#newsletter_index .runner').fadeIn(1000)", 3000);
                }
              });

            } else {
              $("form#newsletter_index .runner").hide();
              $("form#newsletter_index .runner").after("<div class='error'>Please enter a valid email address.</div>");
              setTimeout("$('form#newsletter_index .error').remove();$('form#newsletter_index .runner').fadeIn(1000)", 3000);
            }

            return false;
          }
          function validate_email(email_address) {
             var reg = /^([A-Za-z0-9_\-\.])+\@([A-Za-z0-9_\-\.])+\.([A-Za-z]{2,4})$/;
             if(reg.test(email_address) == false) {
                return false;
             } else {
            return true;
             }
          }

          this.getData = function(){
            return _data;
          }

          return this;
        });
      }

      function ImageSelector(container,data) {
        var _data = data;
        var _selected = -1;
        var _c = $(container);
        var _pageCount;
        var _currentPage = -1;
        var _imgPP;
        var _cWidth;
        var _totalWidth;
        var registration_position = -1;
        var _interjector = -1;
        var _interjected = false;
        var _this = this;
        var IMG_WIDTH = 102;
        var IMG_HEIGHT = 77;
        var SPACING = 5;
        var FADE = .5;
        var FADE_TIME = 100;
        var MOVE_TIME = 200;
        //This checks the gallery has a newsletter, checked in javascript because Nirvana galleries use this too
        if ($('#gallery').attr('class') != "") registration_position = $('#gallery').attr('class');
        init();

        function init(){
          $('div.newsletter_registration').hide();
          $('#gallery').parent().parent().children('div.thumbnail_grid').hide();
          create();
          initCollection();
          initNav();
        }
        function create(){
          var str = "<div class='image-selector clearfix'><ul><li class='nav-btn back'></li><li class='nav-btn prev'></li></ul><div class='collection clearfix'><ul>";
          for(var i=0; i < _data.length; i++) {
            if (i == registration_position) str += "<li id='news_form'><a id='"+_data.length+"' href='#'><img width='100' height='75' alt='' src='"+staticURL+"sites/newsletter/i/100x75.jpg'></a></li>";
            str += "<li><a id='"+i+"' href='#'>"+_data[i].thumb+"</a></li>";
          }
          if (registration_position > _data.length - 1) {
              registration_position = _data.length;
              str += "<li id='news_form'><a id='"+_data.length+"' href='#'><img width='100' height='75' alt='' src='"+staticURL+"sites/newsletter/i/100x75.jpg'></a></li>";
          }
          str += "</ul></div><ul><li class='nav-btn next'></li><li class='nav-btn forward'></li></ul></div>";
          _c.html(str);
        }
        function initCollection() {
          var num_carousel = _data.length;
          if (registration_position > -1) num_carousel++;
          _totalWidth = (num_carousel)*(IMG_WIDTH+SPACING);

          _cWidth = _c.find('div.collection').width();
          _c.find('div.collection ul').width(_totalWidth);
          _imgPP = Math.floor((_cWidth+SPACING)/(IMG_WIDTH+SPACING))-1;
          _pageCount = Math.ceil(_data.length/_imgPP);

          _c.find('div.collection ul li')
            .hover(
                function(e){
                    $(this).fadeTo(FADE_TIME,FADE);
                }, function(e) {
                    if(!$(this).hasClass('selected'))
                    $(this).fadeTo(FADE_TIME,1);
                }
            )
            .click(
                function(e){
                    //Now uses id on anchor tag to know which image should be loaded
                    goTo(parseInt($(this).find('a').attr('id')));
                    e.preventDefault();
                }
            );
        }
        function initNav(){
          //The index for where the image links are on the carousel are now used for the next and previous buttons
          //They now call the click events on the carousel items which detemine image to show or if to show the newsletter form
          _c.find('li.nav-btn.next').click(function(e){
              if($('div.collection ul li.selected').index() < $('div.collection ul li').length - 1) {
                  $('div.collection ul li:eq(' + ($('div.collection ul li.selected').index() + 1) + ")").click();
              }
          });
          _c.find('li.nav-btn.prev').click(function(e) {
              if($('div.collection ul li.selected').index() > 0) {
                  $('div.collection ul li:eq(' + ($('div.collection ul li.selected').index() - 1) + ")").click();
              }
          });
          _c.find('li.nav-btn.forward').click(function(e) {
            if(_currentPage < _pageCount-1) gotoPage(_currentPage+1);
          });
          _c.find('li.nav-btn.back').click(function(e) {
            if(_currentPage > 0) gotoPage(_currentPage-1);
          });
        }
        function goTo(index) {
          if(index >= _data.length) {
    	    if(registration_position > -1) {
    	        _c.find('div.collection ul li.selected').removeClass('selected').fadeTo(FADE_TIME,1);
    	        //Selected relies on the anchor tag now
    	        $('li a#'+index).parent().fadeTo(FADE_TIME,FADE);
    	        $('li a#'+index).parent().addClass('selected');
                _selected = _data.length;
                //Uses the actual position of the newsletter thumbnail to find where and on what carousel page it should be on
                if (registration_position == 0) _c.find('li.nav-btn.prev').addClass('disabled');
                if (registration_position == _data.length) _c.find('li.nav-btn.next').addClass('disabled');
                if (registration_position%_imgPP == 0 && _currentPage == Math.floor(registration_position/_imgPP)) gotoPage(Math.floor((registration_position-1)/_imgPP));
                //The actual index for the newsletter thumbnail must be used as the position may be greater than the number of images
                else gotoPage(Math.floor(($('li#news_form').index()-1)/_imgPP));
                formSelected = false;
                dispatchEvent("INTERJECTED");
                return;
    	    } else {
    	        _this.setSelected(0);
        		return;
    	    }
          }
          if (_interjector == index && !_interjected) {
            _c.find('div.collection ul li.selected').removeClass('selected').fadeTo(FADE_TIME,1);
            //Selected relies on the anchor tag now
            $('li a#'+index).parent().fadeTo(FADE_TIME,FADE);
            $('li a#'+index).parent().addClass('selected');
            _selected = _data.length;
            //Uses the actual position of the newsletter thumbnail to find where and on what carousel page it should be on
            if (registration_position == 0) _c.find('li.nav-btn.prev').addClass('disabled');
            if (registration_position%_imgPP == 0 && _currentPage == Math.floor(registration_position/_imgPP)) gotoPage(Math.floor((registration_position-1)/_imgPP));
            else gotoPage(Math.floor(registration_position/_imgPP));
            _interjected = true;
            formSelected = false;
            dispatchEvent("INTERJECTED");
          }
          else if (_selected != index || (_selected == index && _interjected)) {
            var target = _c.find('div.collection ul li:eq('+index+')');
            //Selected relies on the anchor tag now
            var target = $('li a#'+index).parent();

            _selected = index;
            _c.find('div.collection ul li.selected').removeClass('selected').fadeTo(FADE_TIME,1);
            target.fadeTo(FADE_TIME,FADE);
            target.addClass('selected');
            if (_selected == _data.length-1 && (registration_position == -1 || registration_position < _data.length - 1)) {
                _c.find('li.nav-btn.next').addClass('disabled');
            }
            else _c.find('li.nav-btn.next').removeClass('disabled');
            if (_selected == 0) {
                if (registration_position == _selected) {
                    _c.find('li.nav-btn.prev').removeClass('disabled');
                } else {
                    _c.find('li.nav-btn.prev').addClass('disabled');
                }
            }
            else _c.find('li.nav-btn.prev').removeClass('disabled');
            //Determines the thumbnail's actual position if there's a newsletter form
            if (_selected >= registration_position) {
                if ((_selected+1)%_imgPP == 0 && _currentPage == Math.floor((_selected+1)/_imgPP) || registration_position == -1) gotoPage(Math.floor(_selected/_imgPP));
                else gotoPage(Math.floor((_selected+1)/_imgPP));
            } else {
                if (_selected%_imgPP == 0 && _currentPage == Math.floor(_selected/_imgPP)) gotoPage(Math.floor((_selected-1)/_imgPP));
                else gotoPage(Math.floor(_selected/_imgPP));
            }
            dispatchEvent("CHANGED");
          }
        }
        function gotoPage(index) {
          if(_currentPage != index) {
            var offset = -(_cWidth+SPACING)*index+(IMG_WIDTH+SPACING)*index;

            _currentPage = index;
            if (index == _pageCount-1) offset = _cWidth-_totalWidth+SPACING;
            if (offset > 0) offset = 0;
            $('div.collection ul').animate({left:offset+'px'},MOVE_TIME);
            if (_currentPage >= _pageCount-1) _c.find('li.nav-btn.forward').addClass('disabled');
            else _c.find('li.nav-btn.forward').removeClass('disabled');
            if (_currentPage >= _pageCount-1 && _data.length%_imgPP == 1) {_c.find('li.nav-btn.forward').addClass('disabled');_currentPage--;}
            if (_currentPage <= 0) _c.find('li.nav-btn.back').addClass('disabled');
            else _c.find('li.nav-btn.back').removeClass('disabled');
          }
        }

        this.getSelected = function(){
          return _selected;
        }
        this.setSelected = function(index){
          goTo(index);
        }
        this.getInterjector = function(){
          return _interjector;
        }
        this.setInterjector = function(index){
          _interjector = index;
        }

        var _listeners = {};
        function dispatchEvent(type){
          if(_listeners[type] != undefined){
            for(var i=0; i < _listeners[type].length;i++){
              _listeners[type][i](_this);
            }
          }
        }
        this.addEventListener = function(type,listener){
          if(_listeners[type] == undefined) _listeners[type] = new Array();
          _listeners[type].push(listener);
        }
      }
    })(jQuery);

    $(document).ready(function(e) {
    	setTimeout(function() {
        $.ajax({
    		url: 'http://images.nationalgeographic.com/wpf/sites/common/j/jquery.address-1.3.1-grant.min-cb1299116789.js',
    		dataType: 'script',
    		timeout: 1500,
    		success: 	function() {
    					var startImage;
    					  $.address.init(function(e) {
    					    startImage = $.address.pathNames()[0];
    					    $('#gallery_loader').remove();
    					    $('#gallery').ng_gallery({startImage:startImage});
    					    $('#gallery').parent('.subsection').fadeOut(0).css('visibility','visible').fadeIn(200);
    					  });	
    				    $('#gallery_loader').remove();
    				},
    		error: function() {
    			$('#gallery_loader').hide();
    		},	
    		complete: function(status) {
    				// For whatever reason, jQuery is not returning a status to this complete callback... weird.
    				$('#gallery_loader').remove();
    			}
    	});
    	}, 1500);
    });
