"use strict";
(function( $, window, document, undefined ) {
var settings;
function chain() {
return $(".column > .selected");
}
function breadcrumb() {
var $breadcrumb = $("div.breadcrumb").empty();
chain().each( function( item, crumb ) {
$("<span/>").text( $(crumb).text().trim() ).appendTo( $breadcrumb );
});
}
function animation( $columns, $column ) {
$columns.animate( { scrollLeft: $column.offset().left }, settings.delay );
}
function unnest( $columns ) {
var queue = [],
$node;
queue.push( $columns.children() );
while( queue.length ) {
$node = queue.shift();
$node.children().each( function( item, el ) {
var $child = $(this).children(),
$ancestor = $(this).parent().parent();
if( $ancestor.length && ($(this).data( "ancestor" ) === undefined) ) {
$(this).siblings().addBack().data( "ancestor", $ancestor );
}
if( $child.length > 0 ) {
queue.push( $child );
$(this).data( "child", $child ).addClass( "parent" );
}
$(this).parent().appendTo( $columns ).addClass( "column" );
});
}
}
function collapse() {
$(".column:gt(0)").addClass( "collapse" );
}
function current() {
return chain().last();
}
function reset() {
collapse();
chain().removeClass( "selected" );
breadcrumb();
settings.current( undefined );
}
function moveU() {
current().prev().click();
}
function moveD() {
current().next().click();
}
function moveL() {
var $ancestor = current().data( "ancestor" );
if( $ancestor !== undefined ) {
$ancestor.click();
}
}
function moveR() {
var $child = current().data( "child" );
if( $child === undefined ) {
moveD();
}
else {
$child.children().first().click();
}
}
function keypress( event ) {
var moved = false;
switch( event.keyCode ) {
case 27:
reset();
break;
case 38:
moveU();
moved = true;
break;
case 40:
moveD();
moved = true;
break;
case 37:
moveL();
moved = true;
break;
case 39:
moveR();
moved = true;
break;
}
if( moved && (current().length === 0) ) {
$(".column").first().children().first().click();
}
}
$.fn.millerColumns = function( options ) {
var defaults = {
current: function( $item ) { return undefined; },
breadcrumb: breadcrumb,
animation: animation,
delay: 500
};
settings = $.extend( defaults, options );
return this.each( function() {
var $columns = $(this);
unnest( $columns );
collapse();
$columns.find( "li" ).on( "click", function( event ) {
reset();
var $child = $(this).data( "child" ),
$ancestor = $(this);
if( $child !== undefined ) {
$child.removeClass( "collapse" ).children().removeClass( "selected" );
}
while( $ancestor !== undefined ) {
$ancestor.addClass( "selected" ).parent().removeClass( "collapse" );
$ancestor = $ancestor.data( "ancestor" );
}
settings.animation.call( this, $columns, $(this) );
settings.breadcrumb.call( this );
settings.current.call( this, $(this) );
event.stopPropagation();
});
$columns.bind( 'keypress', keypress );
$columns.on( "click", function() {
reset();
});
$columns.focus();
});
};
}(jQuery));