$( function() {
$( ".draggable" ).draggable({
	revert: "valid"
});

function actionify(el) {
	el.append();
	return el;
}

$( "#song" ).droppable({
  drop: function( event, ui ) {
	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');
	}
	
	switch(ui.draggable.attr('id')) {
		case 'titleComponent':
			$('<div class="title component"  ondrop="return false;"><h1 class="no-line-breaks type" data-directive="title" contenteditable="true" data-placeholder="type the song title here"></h1></div>')
				.append(actions)
					.appendTo($('#song'));
			break;
		case 'artistComponent':
			$('<div class="artist component" ondrop="return false;"><h2 class="no-line-breaks type" data-directive="artise" contenteditable="true" data-placeholder="type the artist name here"></h2></div>')
				.append(actions)
					.appendTo($('#song'));
			break;
		case 'copyrightComponent':
			$('<div class="copyright component" ondrop="return false;"><h4> &copy <span class="no-line-breaks line type" data-directive="copyright" contenteditable="true" data-placeholder="type the year and copyright holder here"></span></h4></div>')
				.append(actions)
					.appendTo($('#song'));
			break;
		case "chorusComponent":
			$('<div class="chorus component" ondrop="return false;"><h4 data-directive="chorus" contenteditable="true">Chorus</h4><div class="line type" ondrop="return false;" data-placeholder="type your chorus lyrics here.." contenteditable="true"></div></div>')
				.append(actions)
					.appendTo($('#song'));
						break;
		case "verseComponent":
			$('<div class="verse component" ondrop="return false;"><div data-directive="start_of_verse"><em contenteditable="true">Verse</em></div><div class="line type" contenteditable="true" ondrop="return false;" data-placeholder="type your verse lyrics here.."></div></div>')
				.append(actions)
					.appendTo($('#song'));
			break;
		case "chordDiagrams":
			$('<div class="chords component"><div><h2>Chords</h2></div>' + 
				'<img src="chords/C.svg" width="100" draggable="true" ondragstart="drag(event)" data-chord="C">' +
				'<img src="chords/Em.svg" width="100" draggable="true" ondragstart="drag(event)" data-chord="Em">' +
				'<a href="#"> <img src="chords/+.svg" width="100"></a></div>')
				.append(actions)
					.appendTo($('#song'));
		default:
			break;
	}
  }
});

$(document).on('keypress', '.no-line-breaks', function(evt) {
	if (evt.which === 13) {
	   evt.preventDefault();
    }
});

$(document).on('blur', '.no-line-breaks', function(evt) {
	$(this).find('br').remove();
});

$(document).on('click', '.delete', function(evt) {
	evt.preventDefault();
	$(this).parents('.component').remove();
});

$(document).on('click', '.up', function(evt) {
	evt.preventDefault();
	if($(this).parents('.component').prev().length) {
		$(this).parents('.component').prev().before($(this).parents('.component').detach());
	}
});

$(document).on('click', '.down', function(evt) {
	evt.preventDefault();
	if($(this).parents('.component').next().length) {
		$(this).parents('.component').next().after($(this).parents('.component').detach());
	}
});


$(document).on('keydown', '.line', function(evt) {
	console.log("Key down " + evt.which);
	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).text()));
	restoreCaret();
});

$('#toolkit-toggle').click(function(e) {
	e.preventDefault();
	el = $(this).parent();
	if(el.hasClass('maximized')) {
		el.removeClass('maximized');
		el.addClass('minimized');
		$(this).html('<i class="fa-solid fa-chevrons-left"></i>');
		$('#toolkit-contents').addClass('hide');
		$('.actions').removeClass('max');
	} else {
		el.removeClass('minimized');
		el.addClass('maximized');
		$(this).html('<i class="fa-solid fa-chevrons-right"></i>');
		$('#toolkit-contents').removeClass('hide');
		$('.actions').addClass('max');
	}
});

$('#save').click(function(e) {
	
	var fd = new FormData();
	fd.append('content', '<html>' + $('html').html() + '</html>');
	
	$.ajax({
	  type: "POST",
	  url: "/app/api/save",
	  processData: false,
	  data: fd,
	  success: function(response) {
		// Process response
	  },
	  dataType: 'json'
	});
	
});

});

/* HELPERS */
function wrapLetters(textContent) {
  return textContent.split('').map(function(letter) {
    return '<span class="character" ondrop="drop(event)" ondragover="allowDrop(event)">' + letter + '</span>';
  }).join('');
}

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
    }
}

