YUI.add('timeline', function(Y) {
var Lang = Y.Lang,
Widget = Y.Widget,
Node = Y.Node;
var NS = Y.namespace('mazzle');
NS.Timeline = Timeline;
function Timeline(config) {
Timeline.superclass.constructor.apply(this, arguments);
}
Timeline.NAME = "timeline";
Timeline.ATTRS = {
items: {
value: [],
validator: function(val) {
return Y.Lang.isArray(val);
}
},
start: {
value: 0,
validator: function(val) {
return Y.Lang.isNumber(val);
}
},
duration: {
value: null,
validator: function(val) {
return Y.Lang.isNumber(val);
}
},
itemWidth: {
value: 1,
validator: function(val) {
return Y.Lang.isNumber(val);
}
}
};
/* Static constants used to define the markup templates used to create Timeline DOM elements */
Timeline.LIST_CLASS = 'timeline-list';
Timeline.LIST_TEMPLATE = '
';
/* Timeline extends the base Widget class */
Y.extend(Timeline, Widget, {
initializer: function() {
this._timePoints = [];
this._timePointDuration = null;
this._listNode = null;
},
destructor : function() {
},
renderUI : function() {
this._listNode = this.get("contentBox")
.appendChild(Node.create(Timeline.LIST_TEMPLATE));
},
bindUI : function() {
this.after("durationChange", this.syncUI);
this.after("widthChange", this.syncUI);
this.after("itemWidthChange", this.syncUI);
this.after("itemsChange", this.syncUI);
this._bindItemEvents();
},
syncUI : function() {
this._updateTimePointDuration();
this._renderItems();
},
_updateTimePointDuration : function() {
var width = this.get("contentBox").get("offsetWidth"),
itemWidth = this.get("itemWidth"),
duration = this.get("duration");
if(duration) {
this._timePointDuration = (width/itemWidth)/duration;
}
},
_renderItems : function() {
var items = this.get("items"),
itemWidth = this.get("itemWidth"),
timePoints = {},
timePointDuration = this._timePointDuration;
this._listNode.setContent("");
if(items&&timePointDuration) {
for(var i=0; i < items.length; i++) {
var item = items[i],
tag = item.tag,
time = item.time||item.startTime;
// The timepoint to which an item is added
// depends on the duration of individual time points.
// Depending on the scale multiple items can be shared on a time point.
var position = Math.round(timePointDuration*time);
if(timePoints[position]) {
var timePoint = timePoints[position];
item.node = timePoint.node;
timePoint.items.push(i);
} else {
item.node = this._listNode
.appendChild(Node.create(''))
.setStyle('marginLeft', position)
.setStyle('width', itemWidth);
timePoints[position] = {
node: item.node,
items: [i]
};
}
}
}
this._timePoints = timePoints;
},
_bindItemEvents : function() {
// item mouse over
Y.delegate("mouseover", function(e) {
var index = e.container.all("li").indexOf(e.currentTarget),
items = this._timePoints[index];
this.fire("itemMouseOver", {
items:items, target:e.currentTarget, index:index});
}, this._listNode, "li", this);
// item click
Y.delegate("click", function(e) {
var index = e.container.all("li").indexOf(e.currentTarget),
items = this._timePoints[index];
this.fire("itemSelect", {
items:items, target:e.currentTarget, index:index});
}, this._listNode, "li", this);
},
/* updateToInterval
*
* groups is an object with as a key the index
* of the item that should be updated to an interval
*/
updateToInterval : function(groups, interval) {
var items = this.get("items"),
itemWidth = this.get("itemWidth");
// First we reset everything
this._listNode.all("li").each(function(node, index) {
node.setStyle("width", itemWidth)
.removeClass("hidden")
.removeClass("interval");
});
if(groups&&interval) {
itemWidth = itemWidth*(this._timePointDuration*interval);
for (var i=0; i < items.length; i++) {
var node = items[i].node;
if(groups[i]) {
node.setStyle("width", itemWidth)
.addClass("interval")
.removeClass("hidden");
} else if(!node.hasClass("interval")){
node.addClass("hidden");
}
}
}
},
highlightTag : function(tag) {
var items = this.get("items");
for (var i=0; i < items.length; i++) {
var item = items[i];
if(item.tag == tag) {
this._highlight(item.node);
}
};
},
highlightIndex : function(index) {
var item = this.get("items")[index];
if(item) {
this._highlight(item.node);
}
},
_highlight : function(node) {
// removeFocus from all items
this._listNode.all("li").removeClass('highlight');
// and highlight the node of the item at index
if(node) {
node.addClass('highlight');
}
}
});
}, 'gallery-2010.03.02-18', {requires:['node','anim','widget']});