define(['jquery'], function($){
"use strict";
var ScrollManager = function(notebook, options) {
this.notebook = notebook;
this.element = $('#site');
options = options || {};
this.animation_speed = options.animation_speed || 250;
};
ScrollManager.prototype.scroll = function (delta) {
this.scroll_some(delta);
return false;
};
ScrollManager.prototype.scroll_to = function(selector) {
this.element.animate({'scrollTop': $(selector).offset().top + this.element.scrollTop() - this.element.offset().top}, this.animation_speed);
};
ScrollManager.prototype.scroll_some = function(pages) {
this.element.animate({'scrollTop': this.element.scrollTop() + pages * this.element.height()}, this.animation_speed);
};
ScrollManager.prototype.get_first_visible_cell = function() {
var cell_count = this.notebook.ncells();
var first_cell_top = this.notebook.get_cell(0).element.offset().top;
var last_cell_top = this.notebook.get_cell(cell_count-1).element.offset().top;
var avg_cell_height = (last_cell_top - first_cell_top) / cell_count;
var i = Math.ceil(this.element.scrollTop() / avg_cell_height);
i = Math.min(Math.max(i , 0), cell_count - 1);
while (this.notebook.get_cell(i).element.offset().top - first_cell_top < this.element.scrollTop() && i < cell_count - 1) {
i += 1;
}
while (this.notebook.get_cell(i).element.offset().top - first_cell_top > this.element.scrollTop() - 50 && i >= 0) {
i -= 1;
}
return Math.min(i + 1, cell_count - 1);
};
var TargetScrollManager = function(notebook, options) {
ScrollManager.apply(this, [notebook, options]);
};
TargetScrollManager.prototype = Object.create(ScrollManager.prototype);
TargetScrollManager.prototype.is_target = function (index) {
return false;
};
TargetScrollManager.prototype.scroll = function (delta) {
var cell_count = this.notebook.ncells();
var selected_index = this.get_first_visible_cell() + delta;
while (0 <= selected_index && selected_index < cell_count && !this.is_target(selected_index)) {
selected_index += delta;
}
if (selected_index < 0 || cell_count <= selected_index) {
return ScrollManager.prototype.scroll.apply(this, [delta]);
} else {
this.scroll_to(this.notebook.get_cell(selected_index).element);
return false;
}
};
var SlideScrollManager = function(notebook, options) {
TargetScrollManager.apply(this, [notebook, options]);
};
SlideScrollManager.prototype = Object.create(TargetScrollManager.prototype);
SlideScrollManager.prototype.is_target = function (index) {
var cell = this.notebook.get_cell(index);
return cell.metadata && cell.metadata.slideshow &&
cell.metadata.slideshow.slide_type &&
(cell.metadata.slideshow.slide_type === "slide" ||
cell.metadata.slideshow.slide_type === "subslide");
};
var HeadingScrollManager = function(notebook, options) {
ScrollManager.apply(this, [notebook, options]);
options = options || {};
this._level = options.heading_level || 1;
};
HeadingScrollManager.prototype = Object.create(ScrollManager.prototype);
HeadingScrollManager.prototype.scroll = function (delta) {
var headers = $();
var i;
for (i = 1; i <= this._level; i++) {
headers = headers.add('#notebook-container h' + i);
}
var first_cell_top = this.notebook.get_cell(0).element.offset().top;
var current_scroll = this.element.scrollTop();
var header_scroll = 0;
i = -1;
while (current_scroll >= header_scroll && i < headers.length) {
if (++i < headers.length) {
header_scroll = $(headers[i]).offset().top - first_cell_top;
}
}
i--;
if (i < 0 || current_scroll > $(headers[i]).offset().top - first_cell_top + 30) {
if (delta < 0) {
delta += 1;
}
}
i += delta;
if (0 <= i && i < headers.length) {
this.scroll_to(headers[i]);
return false;
} else {
return ScrollManager.prototype.scroll.apply(this, [delta]);
}
};
return {
'ScrollManager': ScrollManager,
'SlideScrollManager': SlideScrollManager,
'HeadingScrollManager': HeadingScrollManager,
'TargetScrollManager': TargetScrollManager
};
});