$( function() {
	
	var transpose = $('body').data('transpose') ? $('body').data('transpose') : 0;
	
	$( ".draggable" ).draggable({
		revert: "valid"
	});
	
	if($('body').data('transpose') > 0) {
		$('#transposeDown').after('<small class="transpose">+' + $('body').data('transpose') + '</small>');
	} else if($('body').data('transpose') < 0) {
		$('#transposeDown').after('<small class="transpose">' + $('body').data('transpose') + '</small>');
	}

	$('#transposeDown').click(function(e) {
		e.preventDefault();
		if(transpose > -12) {
			window.location = '/app/ui/wysiwyg-editor/' + $('body').data('uuid') + '/' + --transpose;
		}
	});
	
	$('#transposeUp').click(function(e) {
		e.preventDefault();
		if(transpose < 12) {
			window.location = '/app/ui/wysiwyg-editor/' + $('body').data('uuid') + '/' + ++transpose;
		}
	});
		
	$( "#song" ).droppable({
	  drop: function( event, ui ) {
		var actions = getActions();
		dirty();
		switch(ui.draggable.attr('id')) {
			case 'titleComponent':
				$.getJSON('/app/api/songs/component/TITLE', function(data) {
					if(data.success) {
						$(data.message).append(actions).appendTo($('#song'));
					}
				});
				break;
			case 'artistComponent':
				$.getJSON('/app/api/songs/component/ARTIST', function(data) {
					if(data.success) {
						$(data.message).append(actions).appendTo($('#song'));
					}
				});
				break;
			case 'copyrightComponent':
				$.getJSON('/app/api/songs/component/COPYRIGHT', function(data) {
					if(data.success) {
						$(data.message).append(actions).appendTo($('#song'));
					}
				});
				break;
			case "chorusComponent":
				$.getJSON('/app/api/songs/component/CHORUS', function(data) {
					if(data.success) {
						$(data.message).append(actions).appendTo($('#song'));
					}
				});
				break;
			case "repeatChorusComponent":
				$.getJSON('/app/api/songs/component/REPEAT_CHORUS', function(data) {
					if(data.success) {
						$(data.message).append(actions).appendTo($('#song'));
					}
				});
				break;
			case "pageBreakComponent":
				$.getJSON('/app/api/songs/component/PAGE_BREAK', function(data) {
					if(data.success) {
						$(data.message).append(actions).appendTo($('#song'));
					}
				});
				break;
			case "verseComponent":
				$.getJSON('/app/api/songs/component/VERSE', function(data) {
					if(data.success) {
						$(data.message).append(actions).appendTo($('#song'));
					}
				});
				break;
			case "chordDiagrams":
				$.getJSON('/app/api/songs/component/CHORD', function(data) {
					if(data.success) {
						$(data.message).append(actions).appendTo($('#song'));
						renderPageChords();
					}
				});
				
			default:
				break;
		}
	  }
	});

	$(document).on('keypress', '.no-line-breaks', function(evt) {
		if (evt.which === 13) {
		   evt.preventDefault();
	    }
		dirty();
	});
	
	$(document).on('blur', '.no-line-breaks', function(evt) {
		$(this).find('br').remove();
		dirty();
	});
	
	$(document).on('click', '.delete', function(evt) {
		evt.preventDefault();
		$(this).parents('.component').remove();
		dirty();
	});
	
	$(document).on('click', '.up', function(evt) {
		evt.preventDefault();
		if($(this).parents('.component').prev().length) {
			$(this).parents('.component').prev().before($(this).parents('.component').detach());
			dirty();
		}
	});
	
	$(document).on('click', '.down', function(evt) {
		evt.preventDefault();
		if($(this).parents('.component').next().length) {
			$(this).parents('.component').next().after($(this).parents('.component').detach());
			dirty();
		}
	});


	$(document).on('keydown', '.line', function(evt) {
		console.log("Key down " + evt.which);
		dirty();
		if (evt.which === 13) {
		    evt.preventDefault();
			$(this).after('<div class="line" ondrop="return false;" contenteditable="true"></div>');
			$(this).next().focus();
			return false;
		} else if(evt.which === 8) {
			if($(this).text() === '') {
				evt.preventDefault();
				console.log("Line is empty so it will be removed");
				if($(this).prev()) {
					$(this).prev().focus();
					setEndOfContenteditable($(this).prev().get(0));
					$(this).remove();
				}
	
			}
		} else if(evt.which === 38) {
			evt.preventDefault();
			if($(this).prev().length) {
				$(this).prev().focus();
				setEndOfContenteditable($(this).prev().get(0));
			}
		} else if(evt.which === 40) {
			evt.preventDefault();	
			if($(this).next().length) {
				$(this).next().focus();
				setEndOfContenteditable($(this).next().get(0));
			}
		}
	});
	
	$(document).on('blur', '.line', function(evt) {
		restoreCaret = saveCaretPosition(this);
		$(this).html(wrapLetters($(this)));
		restoreCaret();
		dirty();
	});

	$('#toolkit-toggle').click(function(e) {
		e.preventDefault();
		el = $(this).parent();
		if(el.hasClass('maximized')) {
			el.removeClass('maximized');
			el.addClass('minimized');
			$(this).html('<i class="' + $('body').data('iconset') + ' fa-chevrons-left"></i>');
			$('#toolkit-contents').addClass('hide');
			$('.actions').removeClass('max');
		} else {
			el.removeClass('minimized');
			el.addClass('maximized');
			$(this).html('<i class="' + $('body').data('iconset') + ' fa-chevrons-right"></i>');
			$('#toolkit-contents').removeClass('hide');
			$('.actions').addClass('max');
		}
	});
	
	$('#exit').click(function(e) {
		e.preventDefault();
		doSave(function() {
			var redirect = $('body').data('redirect');
			if(redirect)
				window.location = redirect;
			else
				window.location = '/';
		});
	});
	
	$('#save').click(function(e) {
		e.preventDefault();
		doSave(function() {
			window.location = '/app/ui/wysiwyg-editor/' + $('body').data('uuid');
		});
	});
	
	$('#download').click(function(e) {
			e.preventDefault();
			doSave(function() {
				window.location = '/app/api/songs/download/' + $('body').data('uuid');
			});
		});
	
	$('#print').click(function(e) {
			e.preventDefault();
			doSave(function() {
				window.location = '/app/ui/print-song/' + $('body').data('uuid');
			});
	});

	$('#close-chords').click(function(e) {
		e.preventDefault();
		$('#chord-selector').addClass("hide");
	});
	
	$(document).on('click', '#chordSelector', function(e) {
		e.preventDefault();
		$('#chord-selector').removeClass("hide");
	});
	
	$(document).on('keyup', '#addChord', function(e) {
		if(e.which == 13) {
			$('#addChord').removeClass('inputError');
			var chord = $(this).val();
			$(this).val('');
			$.getJSON( "/app/api/chord/select/" + encodeURIComponent(chord), function(data) {
		        if(data.success) {
					$('#chordSelection').empty();
					$('#chordSelection').append(data.message);
					renderPageChords();
					$('#chordSelection div').wrap('<a href="#" class="selectChord"></a>');
				} else {
					$('#addChord').addClass('inputError');
				}
			});
		}
	});
	
	$(document).on('click', '.selectChord', function(e) {
		e.preventDefault();
		$('#chordSelector').before($(this).children('div').append('<a href="#" class="deleteChord"><i class="fa-thin fa-trash"></i></a>'));
		dirty();
		$('#chordSelection').empty();
		$("#chord-selector").addClass('hide');
	});
	
	$(document).on('click', '.deleteChord', function(e) {
		e.preventDefault();
		$(this).parents('div').first().remove();
	});
	
	$("#chord-selector").draggable();
	
	$('.component').each(function() {
		$(this).append(getActions());
	});
	
	$('#newUser').click(function() {
		var cont = true;
		if (!$('#name')[0].checkValidity()) {
		   $('#name')[0].reportValidity();
		   cont = false;
		}
		if (!$('#emailAddress')[0].checkValidity()) {
		   $('#emailAddress')[0].reportValidity();
		   cont = false;
		}
		 
		if(cont) {
			$.post('/app/api/songs/newUser', 
				{ name: $('#name').val(), emailAddress: $('#emailAddress').val(), marketing: $('#marketing').is(':checked') ? 'true' : 'false' }
				, function(data) {
			 		if(data.success) {
						window.location = "/app/ui/login";
					} else {
						alert(data.message);
					}
			}, 'json');
		}
	});
	
	
	if(transpose !== 0) {
		dirty();
	} else {
		$('#save i').addClass('saved');
	}
});

function doSave(callbackFunc) {
	var uuid = $('body').data('uuid');
	if(uuid === 'NEW') {
		$('#signup').removeClass('hide');
	} else {
		$.ajax({
		  type: "POST",
		  url: "/app/api/songs/save/" + $('body').data('uuid'),
		  data:  { content: '<div id="song">' + $('#song').html() + '</div>'},
		  success: function(response) {
			if(!response.success) {
				alert(response.message);
			} else {
				callbackFunc();
			}
		  },
		  dataType: 'json'
		});
	}	
}

function dirty() {
	$('#save i').addClass('dirty');	
}

function getActions() {
	var actions = 	$('<span class="actions">' + 
					'<a class="delete action" href="#"><sup><i class="fa-thin fa-trash"></i></sup></a>' + 
					'<a class="up action" href="#"><sup><i class="fa-thin fa-arrow-up"></i></sup></a>' + 
					'<a class="down action" href="#"><sup><i class="fa-thin fa-arrow-down"></i></sup></a></span>');
	if($('#toolkit').hasClass('maximized')) {
		actions.addClass('max');
	}
	return actions;
}
/* HELPERS */
function wrapLetters(textContent) {

	var result = '';
	textContent.contents().each(function(idx, text) {
		if(this.nodeType === 3) {
			result += this.nodeValue.split('').map(function(letter) {
				if(letter === "\n") {
					return '';
				}
			    return '<span class="character" ondrop="drop(event)" ondragover="allowDrop(event)">' + letter + '</span>';
			}).join('');
			  
		} else {
			if(this.tagName === 'SPAN') {
				if($(this).hasClass('chord')) {
					result += '<span class="character chord" ondrop="drop(event)" ondragover="allowDrop(event)" data-chord="' + $(this).data('chord') + '">' + $(this).text() + '</span>';
				} else {
					result += '<span class="character" ondrop="drop(event)" ondragover="allowDrop(event)">' + $(this).text() + '</span>';
				}
			}
		}
	});
  
	return result;
}

function saveCaretPosition(context) {
  var selection = window.getSelection();
  var range = selection.getRangeAt(0);
  range.setStart(context, 0);
  var len = range.toString().length;

  return function restore() {
    var pos = getTextNodeAtPosition(context, len);
    selection.removeAllRanges();
    var range = new Range();
    range.setStart(pos.node, pos.position);
    selection.addRange(range);

  }
}

function getTextNodeAtPosition(root, index) {
  var lastNode = null;

  var treeWalker = document.createTreeWalker(root, NodeFilter.SHOW_TEXT, function next(elem) {
    if (index > elem.textContent.length) {
      index -= elem.textContent.length;
      lastNode = elem;
      return NodeFilter.FILTER_REJECT
    }
    return NodeFilter.FILTER_ACCEPT;
  });
  var c = treeWalker.nextNode();
  return {
    node: c ? c : root,
    position: c ? index : 0
  };
}

function allowDrop(ev) {
  //ev.preventDefault();
}

function drag(ev) { 
  ev.dataTransfer.clearData();
  ev.dataTransfer.dropEffect = "none";
  ev.dataTransfer.setData("text/plain", ev.target.dataset['chord']);
}

function drop(ev) {
  
  ev.preventDefault();
  console.log('Dropping ' + ev.target.tagName);
  var data = ev.dataTransfer.getData("text/plain");
  var el = ev.target;
  while(el!==null && el.tagName !== 'SPAN') {
	el = el.nextElementSibling;
  }
  if(el!=null) {
	  console.log('Dropping on ' + el.tagName + ' with content ' + el.textContent);
	  el.classList.add("chord");
	  el.dataset['chord'] = data;
  }

 
}

function setEndOfContenteditable(contentEditableElement)
{
    var range,selection;
    if(document.createRange)//Firefox, Chrome, Opera, Safari, IE 9+
    {
        range = document.createRange();//Create a range (a range is a like the selection but invisible)
        range.selectNodeContents(contentEditableElement);//Select the entire contents of the element with the range
        range.collapse(false);//collapse the range to the end point. false means collapse to end rather than the start
        selection = window.getSelection();//get the selection object (allows you to change selection)
        selection.removeAllRanges();//remove any selections already made
        selection.addRange(range);//make the range you have just created the visible selection
    }
    else if(document.selection)//IE 8 and lower
    { 
        range = document.body.createTextRange();//Create a range (a range is a like the selection but invisible)
        range.moveToElementText(contentEditableElement);//Select the entire contents of the element with the range
        range.collapse(false);//collapse the range to the end point. false means collapse to end rather than the start
        range.select();//Select the range (make it the visible selection
    }
}