(function($) {

function viewToArray($view) {
  $view = $($view);
  var j = [];
  $view.find(".views-row").each(function() {
    $row = $(this);
    var title = $row.find(".views-field-title, .title, h2").text();
	var subtitle = $row.find(".views-field-description .field-content, .description .field-content, .subtitle .field-content, .views-field-subtitle .field-content, .views-field-body, .field-body, .body").text();
	var images = [], i = 0;
	$row.find("img").each(function() { images[i] = $(this).attr('src'); i++; });
	var link = $row.find("a").attr('href');
	var className = $row[0].className;
	var type = $row.find(".views-field-type .field-content, .type .field-content").text();
	j.push({ title: title, subtitle: subtitle, images: images, link: link, className: className, type: type });
  });
  return j;
}

function bloxScroller() {
  var settings = {
    blockSize: 120,
	padding: 5,
	rows: 4,
	json: null,
	url: null,
	footer: null
  };
  
  var self = this;
  var $this;
  var $blocks;
  var $container;
  
  var xstart = 0.0;
  var xvel = 0.0;
  var timer;
  var cancelClick = false;
  var delta = 0;
  
  var ltX = 0, rtX = 0;
  var ltBlock = 0, rtBlock = 0;
  var ltXpos = 0, rtXpos = 0;
  
  var dragging = false;
  var xdrag = 0;
  var rows;
  var blocksWidth = 0;
  var blocks = null;
  
  this.obj = null;
  
  var mousedown = function(e) {
	xstart = e.pageX;
	ystart = e.pageY;
	xdrag = 0;
	dragging = true;
	$(document).bind("mousemove", mousemove);
	$(document).bind("mouseup", mouseup);
	cancelClick = false;
	return false;
  };

  var mouseup = function(e) {
	dragging = false;
	$(document).unbind("mousemove", mousemove);
	$(document).unbind("mouseup", mouseup);
	return !cancelClick;
  };
  
  var mousemove = function(e) {
	if (dragging) {
	  xdrag = parseInt(e.pageX - xstart, 10);
	  if (!timer) timer = setInterval(bloxTimer,25);
	  cancelClick = true;
	}
  };
  
  var click = function(e) {
    return !cancelClick;
  };
  
  var timerUpdating = false;
  var bloxTimer = function() {
    delta++;
	
    if (!timerUpdating) {
	  timerUpdating = true;
	  var d = delta;
	  
	  /* BUILD BLOCKS */
	  self.makeNextBlocks();
	  self.cleanEdgeBlocks();
	  
	  /* MOVE BLOCKS */
	  for(var i=0; i<d; i++) {
	    xvel = dragging ? ((xvel + xdrag * 0.4) + 1) * 0.4 - 1 : (xvel + 1) * 0.9 - 1;
	  }
	  
	  if (Math.abs(xvel + 1) < 0.01) xvel = -1;
	  rtXpos += xvel * d;
	  ltXpos += xvel * d;
	  xstart += xvel * d;
	  xdrag -= xvel * d;
	  
	  $blocks.children().each(function() {
	    $(this).data('x', $(this).data('x') + xvel * d);
	    $(this).css('left', Math.round($(this).data('x')));
	  });
	  
	  delta = 0;
	}
	timerUpdating = false;
  };
  
  this.init = function( selector, options ) {
	$.extend( settings, options );
    $this = $("<div class='blox'><div class='blox-blocks-wrapper blox-loading'><div class='blox-blocks'></div></div></div>");
	
	$this.data('bloxScroller', self);
	selector.data('bloxScroller', self);
	
	selector.empty();
	selector.append($this);
	
	if (!settings.json && !settings.url) {
	  $this.html( "The 'json' or 'url' properties must be specified to create the blocks" );
	  return;
	}
	
	$blocks = $this.find(".blox-blocks");
	$container = $this.find(".blox-blocks-wrapper");
	
	$this.css('height', settings.rows * settings.blockSize + (settings.rows + 1) * settings.padding);
	$container.css('height', settings.rows * settings.blockSize + (settings.rows + 1) * settings.padding);
	
	this.reload();
  };
  
  var loaded = function( data ) {
	if (settings.footer) $this.parent().append($("<div class=\"blox-footer\">" + settings.footer + "</div>").fadeIn());
	
	self.obj = data;
	for(var i=0; i < self.obj.length; i++) {
	  if (!self.obj[i].images) {
	    self.obj[i].images = [];
	    if (self.obj[i].image) self.obj[i].images[0] = self.obj[i].image;
	    if (self.obj[i].image1) self.obj[i].images[0] = self.obj[i].image1;
	    if (self.obj[i].image2) self.obj[i].images[1] = self.obj[i].image2;
	    if (self.obj[i].image3) self.obj[i].images[2] = self.obj[i].image3;
	    if (self.obj[i].image4) self.obj[i].images[3] = self.obj[i].image4;
	    if (self.obj[i].image5) self.obj[i].images[4] = self.obj[i].image5;
	  }
	}
	
	self.rebuild();
	if (!timer) timer = setInterval(bloxTimer, 25);
	
	$container.removeClass("blox-loading");
	
	$container.mousedown(mousedown);
	$container.mouseup(mouseup);
	$container.mousemove(mousemove);
  };
  
  this.reload = function( callback ) {
	if (settings.json) {
	  if (callback) callback( settings.json );
	  loaded( settings.json );
	} else {
	  $.getJSON( settings.url, null, function(data) { if (callback) { callback(data); } loaded(data); } );
	}
  };
  
  this.rebuild = function() {
    rows = new Array(settings.rows);
	for(var i=0; i<rows.length; i++) { rows[i] = "     "; }
	
	ltX = 2; rtX = 3; ltBlock = this.obj.length - 1; rtBlock = 0;
	ltXpos = $this.offset().left - settings.padding - settings.blockSize;
	rtXpos = $this.offset().left;
	
    $blocks.empty();
	blocks = new Array();
  };
  
  var makeBlockHtml = function(data) {
    var title = data.title;
	var subtitle = data.subtitle;
	var link = data.link;
	var image = data.images[Math.floor(Math.random() * data.images.length)];
	var tag = link ? "a" : "span";
	var classes = (data.className ? data.className + " " : "") + (data.type ? data.type : "");
	
	var block = link ? $("<a class=\"blox-block " + classes + "\" href=\"" + link + "\"></a>") : $("<span class=\"blox-block " + classes + "\"></span>");
	var img = image ? "<span class=\"blox-image\"><img src=\"" + image + "\" /></span>" : "";
	block.append($(img + "<span class=\"blox-content\"><span class=\"blox-title\">" + title + "</span><span class=\"blox-subtitle\">" + subtitle + "</span></span>"));
	
	return block;
  };
  
  this.makeNextBlocks = function() {
	// find first free space
	if (rtXpos < $(document).width() + settings.blockSize) {
	  for(var row=0; rows[row].charAt(rtX) != " "; row = (row + 1) % rows.length) {
	    if (row == rows.length - 1) {
		  rtX++;
		  rtXpos += settings.blockSize + settings.padding;
		  if (rtX >= rows[0].length - 1) { for(var i=0; i<rows.length; i++) { rows[i] += " "; } }
		}
	  }
	  this.makeNextBlock(rtBlock, rtX, row, 1, rtXpos);
	  rtBlock = (rtBlock + 1) % this.obj.length;
	}

	if (ltXpos > -settings.blockSize) {
	  for(var row=0; rows[row].charAt(ltX) != " "; row = (row + 1) % rows.length) {
	    if (row == rows.length - 1) {
		  ltX--;
		  ltXpos -= settings.blockSize + settings.padding;
		  if (ltX < 1) { for(var i=0; i<rows.length; i++) { rows[i] = " " + rows[i]; } ltX = 1; rtX++; }
		}
	  }
	  this.makeNextBlock(ltBlock, ltX, row, -1, ltXpos);
	  ltBlock = ltBlock - 1; if (ltBlock < 0) ltBlock += this.obj.length;
	}
  };
  
  this.makeNextBlock = function(index, col, row, dir, xPos) {
	var b = makeBlockHtml(this.obj[index]);
	b.click(click);
	
	var style = 0;
	while(style == 0) {
	  style = 1 + Math.floor( Math.random() * 4 )
	  if (style == 4) { // 2x2
	    if (row == rows.length - 1 || rows[row+1].charAt(col) != " ") style = 0;
	  } else if (style == 3) {
	    style = 1;
	  }
	}

	var yPos = row * (settings.blockSize + settings.padding) + settings.padding;
	var bw = 1, bh = 1;

	var c = dir == 1 ? col : col - 1;
	if (style == 2) {
	  rows[row] = rows[row].substr(0, c) + '..' + rows[row].substr(c + 2);
	  b.addClass("blox-two"); b.data('blox-style', 'two');
	  bw = 2;
	} else if(style == 4) {
	  rows[row] = rows[row].substr(0, c) + '..' + rows[row].substr(c + 2);
	  rows[row+1] = rows[row+1].substr(0, c) + '..' + rows[row+1].substr(c + 2);
	  b.addClass("blox-four"); b.data('blox-style', 'four');
	  bw = 2; bh = 2;
	} else {
	  rows[row] = rows[row].substr(0, col) + '.' + rows[row].substr(col + 1);
	  b.addClass("blox-one"); b.data('blox-style', 'one');
	}

	b.data('x', xPos - (bw > 1 && dir < 0 ? settings.blockSize * (bw-1) + settings.padding * (bw-1) : 0));
	b.data('y', yPos);
	b.data('size', style);
	b.data('blox-width', bw);
	b.data('blox-height', bh);
	b.data('row', row);
	
	b.css('left', xPos - (bw > 1 && dir < 0 ? settings.blockSize * (bw-1) + settings.padding * (bw-1) : 0));
	b.css('top', yPos);
	b.css('width', settings.blockSize * bw + settings.padding * (bw - 1));
	b.css('height', settings.blockSize * bh + settings.padding * (bh - 1));
	
	b.fadeIn(200);
	if (dir == 1) blocks.push(b);
	if (dir == -1) blocks.unshift(b);
	
	$blocks.append(b);

	return true;
  };
  
  this.cleanEdgeBlocks = function() {
    for(var bi = 0; bi < 2; bi++) {
	  while(true) {
        
		var b = bi == 0 ? blocks[0] : blocks[blocks.length-1];
		if (!b) break;
		if (b.offset().left >= -settings.blockSize * 4 && b.offset().left < $(document).width() + settings.blockSize * 3) break;
		
		var row = b.data('row');
		var bw = b.data('blox-width');
		var col = bi == 0 ? rows[row].indexOf('.') : rows[row].lastIndexOf('.') - bw + 1;
		
		if (b.data('size') == 1) {
		  rows[row] = rows[row].substr(0, col) + ' ' + rows[row].substr(col + 1);
		} else if (b.data('size') == 2) {
		  rows[row] = rows[row].substr(0, col) + '  ' + rows[row].substr(col + 2);
		} else if (b.data('size') == 4) {
		  rows[row] = rows[row].substr(0, col) + '  ' + rows[row].substr(col + 2);
		  rows[row+1] = rows[row+1].substr(0, col) + '  ' + rows[row+1].substr(col + 2);
		}
		
		if (bi == 0) ltX += bw; else rtX -= bw;
		if (bi == 0) ltXpos += bw * (settings.blockSize + settings.padding); else rtXpos -= bw * (settings.blockSize + settings.padding);
		
		b.remove();
		if (bi == 0) blocks.shift(); else blocks.pop();
		
		break;
	  }
	}
  };
  
  this.reloadJson = function( json, callback ) {
    settings.json = json;
	settings.url = null;
	this.reload( callback );
  };
  
  this.reloadUrl = function( url, callback ) {
    settings.url = url;
	settings.json = null;
	this.reload( callback );
  };
}


$.fn.bloxScroll = function( options ) {
  
  this.reloadJson = function( data, callback ) {
    var scroller = $(this).data('bloxScroller');
	scroller.reloadJson( data, callback );
  }
  
  this.reloadUrl = function( url, callback ) {
    var scroller = $(this).data('bloxScroller');
	$(this).find(".blox-blocks-wrapper").addClass("blox-loading");
	$(this).find(".blox-block").fadeOut();
	scroller.reloadUrl( url, callback );
  }

  return this.each(function() {
    var b = new bloxScroller();
    b.init( $(this), options );
  });
  return this;
  
};

$().ready(function() {
  $("#email-link").attr('href', 'mailto:' + 'seth' + '@' + 'sethjeffery' + '.' + 'com');

  $(".view-music.view-display-id-block_1, .view-portfolio.view-display-id-block_1, .view-blog.view-display-id-block_1, .view-pictures.view-display-id-block_1").each(function() {
    var json = viewToArray($(this));
    $(this).bloxScroll( { json: json, rows: 2, padding: 2, blockSize: 80 } );
  });
});

})(jQuery);

var bloxScroller;
function getAjaxBlox( url ) {
  (function($) {
  
    bloxScroller = $(".view-display-id-page").bloxScroll( { url: url, footer: '<div class="click-and-drag"></div>' } );
	$("#main-menu a").click(function() {
	  var href = $(this).attr('href');
	  if (href.charAt(href.length - 1) == "/") href = "home.json"; else href += ".json";
	  var a = $(this);
	  
	  bloxScroller.reloadUrl(href, function() {
	    a.parent().parent().find("li, a").removeClass("active");
	    a.addClass("active");
		a.parent().addClass("active");
	  });
	  
	  return false;
	});
	
  })(jQuery);
}

function getBlockAjaxBlox( id, url ) {
  bloxScroller = jQuery(id).bloxScroll( { url: url, rows: 2, padding: 2, blockSize: 80 } );
}
;

