From ae7adad5cf4f81e9356a618bf541965ce8131527 Mon Sep 17 00:00:00 2001
From: Ian Gilman <ian@iangilman.com>
Date: Tue, 10 Feb 2015 14:02:41 -0800
Subject: [PATCH] Alternate images (m2)

---
 test/demo/m2/README.md  |  3 +-
 test/demo/m2/index.html |  1 +
 test/demo/m2/js/main.js | 62 +++++++++++++++++++++++++++++++++++++----
 test/demo/m2/js/page.js | 44 +++++++++++++++++++++++++++++
 4 files changed, 103 insertions(+), 7 deletions(-)
 create mode 100644 test/demo/m2/js/page.js

diff --git a/test/demo/m2/README.md b/test/demo/m2/README.md
index 847f90c2..881cfbdb 100644
--- a/test/demo/m2/README.md
+++ b/test/demo/m2/README.md
@@ -10,11 +10,12 @@ http://showcase.iiif.io/viewer/mirador/
 
 ## To Do
 
-* Choosing between multiple versions of a page
 * Detail images overlaid on the page
 * Cropped images
 
 ### Maybe
 
+* Alternates: align with default image
+* Alternates: wait until tiles have loaded before switching
 * Show/hide pages?
 * Lazyloading tilesources?
diff --git a/test/demo/m2/index.html b/test/demo/m2/index.html
index e86c9a39..70c4c486 100644
--- a/test/demo/m2/index.html
+++ b/test/demo/m2/index.html
@@ -6,6 +6,7 @@
         <script type="text/javascript" src='../../lib/jquery-1.9.1.min.js'></script>
         <script src="//d3js.org/d3.v3.min.js" charset="utf-8"></script>
         <script src="js/main.js"></script>
+        <script src="js/page.js"></script>
         <!-- <script src="js/harvard-tilesources.js"></script> -->
         <script src="js/openseadragon-svg-overlay.js"></script>
         <style type="text/css">
diff --git a/test/demo/m2/js/main.js b/test/demo/m2/js/main.js
index 0959cc3e..e14dcb45 100644
--- a/test/demo/m2/js/main.js
+++ b/test/demo/m2/js/main.js
@@ -19,16 +19,27 @@
                 'page'
             ];
 
+            this.pages = this.createPages();
+
+            var tileSources = $.map(this.pages, function(v, i) {
+                return v.tileSource;
+            });
+
             this.viewer = OpenSeadragon({
                 id: "contentDiv",
                 prefixUrl: "../../../build/openseadragon/images/",
                 autoResize: false,
                 showHomeControl: false,
-                tileSources: this.getTileSources()
+                tileSources: tileSources
             });
 
             this.viewer.addHandler('open', function() {
                 self.$el = $(self.viewer.element);
+
+                $.each(self.pages, function(i, v) {
+                    v.tiledImage = self.viewer.world.getItemAt(i);
+                });
+
                 self.setMode({
                     mode: 'thumbs',
                     immediately: true
@@ -40,6 +51,7 @@
                     var result = self.hitTest(self.viewer.viewport.getCenter());
                     if (result) {
                         self.page = result.index;
+                        self.update();
                     }
                 }
             });
@@ -216,6 +228,37 @@
             $.each(this.modeNames, function(i, v) {
                 $('.' + v).toggleClass('active', v === self.mode);
             });
+
+            // alternates menu
+            if (this.$alternates) {
+                this.$alternates.remove();
+                this.$alternates = null;
+            }
+
+            var page = this.pages[this.page];
+            if (page && page.alternates && page.alternates.length) {
+                this.$alternates = $('<select>')
+                    .change(function() {
+                        page.selectAlternate(parseInt(self.$alternates.val(), 10));
+                    })
+                    .appendTo('.nav');
+
+                $('<option>')
+                    .attr('value', -1)
+                    .text(page.label || 'Default')
+                    .appendTo(self.$alternates);
+
+                $.each(page.alternates, function(i, v) {
+                    if (v.label) {
+                        $('<option>')
+                            .attr('value', i)
+                            .text(v.label)
+                            .appendTo(self.$alternates);
+                    }
+                });
+
+                this.$alternates.val(page.alternateIndex);
+            }
         },
 
         // ----------
@@ -585,10 +628,14 @@
         },
 
         // ----------
-        getTileSources: function() {
+        createPages: function() {
+            var self = this;
+
             if (this.tileSources) {
                 return $.map(this.tileSources.slice(0, this.maxImages), function(v, i) {
-                    return new OpenSeadragon.IIIFTileSource(v);
+                    return new self.Page($.extend({
+                        pageIndex: i
+                    }, v));
                 });
             }
 
@@ -656,12 +703,15 @@
                 }
             ];
 
-            var outputs = [];
+            var pages = [];
             for (var i = 0; i < this.maxImages; i++) {
-                outputs.push(inputs[Math.floor(Math.random() * inputs.length)]);
+                pages.push(new this.Page({
+                    pageIndex: i,
+                    tileSource: inputs[Math.floor(Math.random() * inputs.length)]
+                }));
             }
 
-            return outputs;
+            return pages;
         }
     };
 
diff --git a/test/demo/m2/js/page.js b/test/demo/m2/js/page.js
new file mode 100644
index 00000000..6468b513
--- /dev/null
+++ b/test/demo/m2/js/page.js
@@ -0,0 +1,44 @@
+/* global App */
+(function() {
+
+    // ----------
+    var component = App.Page = function(config) {
+        this.label = config.label;
+        this.tileSource = config.tileSource;
+        this.alternates = config.alternates;
+        this.pageIndex = config.pageIndex;
+        this.alternateIndex = -1;
+    };
+
+    // ----------
+    component.prototype = {
+        // ----------
+        selectAlternate: function(index) {
+            var self = this;
+
+            if (index === this.alternateIndex) {
+                return;
+            }
+
+            var tileSource = (index === -1 ? this.tileSource : this.alternates[index].tileSource);
+
+            var tiledImage = App.viewer.world.getItemAt(this.pageIndex);
+            var bounds = tiledImage.getBounds();
+
+            App.viewer.world.removeItem(tiledImage);
+            App.viewer.addTiledImage({
+                tileSource: tileSource,
+                x: bounds.x,
+                y: bounds.y,
+                height: bounds.height,
+                index: this.pageIndex,
+                success: function(event) {
+                    self.tiledImage = event.item;
+                }
+            });
+
+            this.alternateIndex = index;
+        }
+    };
+
+})();