<template>
	<div 
		id="InputNotes" class="master-note-edit" 
		@keyup.esc="close" 
		:class="[{'size-down':(sizeDown == true)},  'position-'+position ]" 
		:style="{'background-color':color, 'color':fontColor}"
	>

		<div v-if="loading" class="loading-note">
			<div class="ui active dimmer">
				<div class="ui text loader">{{loadingMessage}}...</div>
			</div>
		</div>

		<div class="note-top-menu">
			<div @click="close" class="ui button"><i class="green close icon"></i>Close (ESC)</div>
			
			<div @click="onToggleFancyInput" class="ui button">
				Fancy ({{fancyInput?'On':'Off'}})
			</div>

			<div @click="onTogglePinned" class="ui button">
				<i class="pin icon" :class="{green:(pinned == 1)}"></i> {{(pinned == 1)?'pinned':'not pinned'}}
			</div>
			<div @click="onToggleArchived" class="ui button">
				<i class="archive icon" :class="{green:(archived == 1)}"></i> {{(archived == 1)?'archived':'not archived'}}
			</div>

			<span class="relative" v-on:mouseover="showColorPicker = true" v-on:mouseleave="showColorPicker = false">
				<span class="ui icon button">
					<i class="paint brush icon"></i>
				</span>

				<span v-if="showColorPicker" class="color-picker">
					<button @click="onChangeColor" class="ui icon white button"></button>
					<button @click="onChangeColor" class="ui icon red button"></button>
					<button @click="onChangeColor" class="ui icon orange button"></button>
					<button @click="onChangeColor" class="ui icon yellow button"></button>
					<button @click="onChangeColor" class="ui icon olive button"></button>
					<button @click="onChangeColor" class="ui icon green button"></button>
					<button @click="onChangeColor" class="ui icon teal button"></button>
					<button @click="onChangeColor" class="ui icon blue button"></button>
					<button @click="onChangeColor" class="ui icon violet button"></button>
					<button @click="onChangeColor" class="ui icon purple button"></button>
					<button @click="onChangeColor" class="ui icon pink button"></button>
					<button @click="onChangeColor" class="ui icon brown button"></button>
					<button @click="onChangeColor" class="ui icon grey button"></button>
					<button @click="onChangeColor" class="ui icon black button"></button>
				</span>
			</span>
			
			<span class="note-status-indicator">{{statusText}}</span>
		</div>
		
		<div v-if="fancyInput == 1" class="textarea-height no-flow">
			<ckeditor ref="main-edit"
			:editor="editor" @ready="onReady" v-model="noteText" :config="editorConfig" v-on:blur="save" />
		</div>

		<textarea 
			class="textarea-height raw-edit" 
			v-if="fancyInput == 0" 
			v-model="noteText" 
			v-on:blur="save" 
			v-on:keyup="onKeyup"
		/>

		<note-tag-edit :noteId="noteid" :key="'tags-for-note-'+noteid"/>

	</div>
</template>

<script>

	import axios from 'axios'
	import DecoupledEditor from '@ckeditor/ckeditor5-build-decoupled-document';

	//Start working on some plugin, tag plugin, link to other note, interactive checkbox
	class InsertImage extends Plugin {
    init() {
	        console.log( 'InsertImage was initialized' );
	    }
	}
	

	export default {
	name: 'InputNotes',
		props: [ 'noteid', 'position' ],
		components:{
			'note-tag-edit': require('@/components/NoteTagEdit.vue').default
		},
		data(){
			return {
				loading: true,
				loadingMessage: 'Loading Note',
				currentNoteId: 0,
				noteText: '',
				statusText: 'Saved',
				lastNoteHash: null,
				saveDebounce: null, //Prevent save from being called numerous times quickly
				lastSaved: 0,
				updated: 'Never',
				editDebounce: null,
				keyPressesCounter: 0,
				fancyInput: 0, //Default to basic text edit. Upgrade if set to 1
				pinned: 0,
				archived: 0,
				color: '#fff',
				fontColor: '#000',
				sizeDown: false,
				showColorPicker: false, 

				editor: DecoupledEditor,
                editorConfig: {
                	startupFocus: 'end',
                    toolbar: ["alignment", "fontSize", "removeHighlight", "highlight", "bold", "italic", "strikethrough", "underline", "blockQuote", "heading", "link", "numberedList", "bulletedList", "insertTable", "|", "undo", "redo"]
                }
			}
		},
		watch: {
			noteid:function(newVal, oldVal){

				if(newVal == this.currentNoteId){
					return
				}

				if(newVal == oldVal){
					return
				}
				
				this.currentNoteId = newVal
				this.loadNote(this.currentNoteId)
				
			}
		},
		beforeMount(){
			
		},
		beforeDestroy(){

		},
		mounted: function() {

			this.loadNote(this.noteid)
		},
		methods: {
			onToggleFancyInput(){
				if(this.fancyInput == 0){
					this.fancyInput = 1
				} else {
					this.fancyInput = 0;
				}
				//Update last note hash, this will tell note to save next update
				this.lastNoteHash = 0
			},
			onTogglePinned(){
				if(this.pinned == 0){
					this.pinned = 1
				} else {
					this.pinned = 0;
				}
				//Update last note hash, this will tell note to save next update
				this.lastNoteHash = 0
			},
			onToggleArchived(){
				if(this.archived == 0){
					this.archived = 1
				} else {
					this.archived = 0;
				}
				//Update last note hash, this will tell note to save next update
				this.lastNoteHash = 0
			},
			onChangeColor(event){
				//Grab the color of the button clicked
				const style = getComputedStyle(event.target)
				this.color = style['background-color']
				this.fontColor = '#FFF'

				//If background is white, default to colors in CSS
				if(this.color == "rgb(255, 255, 255)" || this.color == '#FFF'){
					this.color = null
					this.fontColor = null
				}

				this.lastNoteHash = 0 //Update hash to force note update on next save
				this.save()
			},
			loadNote(noteId){

				let vm = this

				let doing = ['Loading','Loading','Getting','Fetching','Grabbing','Sequencing','Organizing','Untangling','Processing','Refining','Extracting','Fusing','Pruning','Expanding','Enlarging','Transfiguring','Quantizing','Ingratiating']
				let thing = ['Note','Note','Note','Note','Data','Text','Document','Algorithm','Buffer','Client','Download','File','Frame','Graphics','Hardware','HTML','Interface','Logic','Mainframe','Memory','Media','Nodes','Network','Chaos']
				let p1 = doing[Math.floor(Math.random() * doing.length)]
				let p2 = thing[Math.floor(Math.random() * thing.length)]
				vm.loadingMessage = p1 + ' ' + p2

				
				//Component is activated with NoteId in place, lookup text with associated ID
				if(this.$store.getters.getLoggedIn){
					axios.post('/api/note/get', {'noteId': noteId})
					.then(response => {

						vm.loading = false

						//Set up local data
						vm.currentNoteId = noteId
						vm.noteText = response.data.text
						vm.updated = response.data.updated
						vm.lastNoteHash = vm.hashString(response.data.text)
						vm.color = response.data.color
						if(response.data.pinned != null){
							vm.pinned = response.data.pinned
						}
						vm.archived = response.data.archived

						this.fontColor = '#FFF'
						if(this.color == "rgb(255, 255, 255)" || this.color == '#FFF' || this.color == null){
							this.color = null
							this.fontColor = null
						}

						if(response.data.raw_input == 1){
							this.fancyInput = 1
						}

						//Put focus on note, at the end of the note text
						vm.$nextTick(() => {
							
							// vm.$refs['custom-input'].focus()
						})

					})
				} else {
					console.log('Could not fetch note')
				}
			},
			onReady(editor){

				let vm = this

				// Insert the toolbar before the editable area.
                editor.ui.getEditableElement().parentElement.insertBefore(
                    editor.ui.view.toolbar.element,
                    editor.ui.getEditableElement()
                );

                editor.editing.view.focus()

				// const editor = this.editor;
				const view = editor.editing.view;
				const viewDocument = view.document;

				//Insert 5 spaces when tab is pressed
				viewDocument.on( 'keyup', ( evt, data ) => {

					vm.onKeyup(event)

					//Optional data bindings for tab key
					if( (data.keyCode == 9) && viewDocument.isFocused ){
				              
				        //Insert 5 spaces to simulate tab
				        //editor.execute( 'input', { text: "      " } );
				   
				        evt.stop(); // Prevent executing the default handler.
				        data.preventDefault();
				        view.scrollToTheSelection();
					}

				} );
			},
			//Used by simple editor
			onKeyup(){
				let vm = this
				vm.statusText = 'Modified'
				//Each note, save after 5 seconds, focus lost or 30 characters typed.
				clearTimeout(vm.editDebounce)
				vm.editDebounce = setTimeout(() => {
					vm.save()
				}, 5000)
				//Save after 30 keystrokes
				vm.keyPressesCounter = (vm.keyPressesCounter + 1)
				if(vm.keyPressesCounter > 30){
					vm.keyPressesCounter = 0
					vm.save()
				}
			},
			save(){
				return new Promise((resolve, reject) => {
					clearTimeout(this.editDebounce)

					//Don't save note if its hash doesn't change
					if( this.lastNoteHash == this.hashString(this.noteText) ){
						resolve(false)
						return
					}
					
					const postData = {
						'noteId':this.currentNoteId,
						'text': this.noteText,
						'fancyInput': this.fancyInput,
						'color': this.color,
						'pinned': this.pinned,
						'archived':this.archived,
					}

					let vm = this
					//Only save every 1 second
					clearTimeout(this.saveDebounce)
					this.saveDebounce = setTimeout(() => {
						//Only notify user if saving - may help with debugging in the future
						vm.statusText = 'Saving'
						axios.post('/api/note/update', postData).then( response => {
							vm.statusText = 'Saved'
							vm.updated = Math.round((+new Date)/1000)

							//Update last saved note hash
							vm.lastNoteHash = vm.hashString(vm.noteText)
							resolve(true)
							return
						})
					}, 300)
				})
				
			},
			hashString(text){
				var hash = 0;
				if (text.length == 0) {
					return hash;
				}
				for (let i = 0; i < text.length; i++) {
					let char = text.charCodeAt(i);
					hash = ((hash<<5)-hash)+char;
					hash = hash & hash; // Convert to 32bit integer
				}
				return hash;
			},
			close(){
				this.sizeDown = true
				this.save().then( result => {
					//Save has a 300 ms timeout, if it saves animation will complete
					if(result){
						this.$bus.$emit('close_active_note', this.position)
						return
					} else {
						//If save is not called, set timeout manually and then close after animation
						setTimeout(() => {
							this.$bus.$emit('close_active_note', this.position)
						}, 300)
					}
				})
				
			}
		}
	}
</script>

<style type="text/css" scoped>
	
	.no-flow {
		overflow: hidden;
	}

	.raw-edit {
		font-family: 'Open Sans' !important;
		font-size: 1.3rem !important;
		background: rgba(0,0,0,0);
		width: 100%;
		resize: none;
		padding: 15px;
		border: 1px solid;
	}

	.note-top-menu {
		width: 100%;
		display: inline-block;
	}

	/* container styles change based on mobile and number of open screens */
	.master-note-edit {
		position: fixed;
		bottom: 0;
		background: var(--background_color);
		/*color: var(--text_color);*/
		height: 100vh;
		box-shadow: 0px 0px 5px 2px rgba(140,140,140,1);
		z-index: 1001;
	}
	.loading-note {
		position: absolute;
		top: 38px;
		left: 0;
		right: 0;
		bottom: 50px;
	}
	/* One note open, in the middle of the screen */
	.master-note-edit.position-0 {
		left: 30%;
		right: 0;
	}
	@media only screen and (max-width: 740px) {
		.master-note-edit.position-0 {
			left: 0;
			right: 0;
			top: 0;
			bottom: 0;
		}
	}

	/* Two Notes Open, each takes up 50% of the space */
	.master-note-edit.position-1 {
		left: 50%;
		right: 0%;
	}
	.master-note-edit.position-2 {
		left: 0%;
		right: 50%;
	}

	.size-down {
		animation: size-down 0.5s ease;
	}

	@keyframes size-down {
		0% {
			opacity: 1;
			top: 0;
		}
		100% {
			opacity: 0;
			top: 30vh;
		}
	}

</style>