<!--
 ~ Copyright 2022 youngmonkeys.org
 ~ 
 ~ Licensed under the ezyplatform, Version 1.0.0 (the "License");
 ~ you may not use this file except in compliance with the License.
 ~ You may obtain a copy of the License at
 ~ 
 ~     https://youngmonkeys.org/licenses/ezyplatform-1.0.0.txt
 ~ 
 ~ Unless required by applicable law or agreed to in writing, software
 ~ distributed under the License is distributed on an "AS IS" BASIS,
 ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 ~ See the License for the specific language governing permissions and
 ~ limitations under the License.
-->

<!DOCTYPE html>

<html xmlns:th="http://www.thymeleaf.org">
<body>
<th:block th:fragment="content">
	<div th:if="${includeMediaModal != false}" class="modal fade" id="media-modal">
		<div class="modal-dialog modal-xl">
			<div class="modal-content">
				<div class="modal-header">
					<div class="d-flex">
						<h4 class="modal-title">[[#{media}]]</h4>
						<button type="button" class="btn btn-outline-primary ml-3"
						        th:if="${adminRoles.isAccessible('/api/v1/media/add', 'POST')}"
								onclick="ezyadmin.showAddNewMediaModal();">
							[[#{add_new}]]
						</button>
						<button type="button" class="btn btn-outline-info ml-3 d-none" id="selectMediasButton"
						        onclick="ezyadmin.onSelectMediasButtonClicked();">
							[[#{select}]]
						</button>
					</div>
					<button type="button" class="close" data-dismiss="modal" aria-label="Close">
						<span aria-hidden="true">&times;</span>
					</button>
				</div>
				<div class="modal-body max-height-85vn-scroll">
					<div class="px-2 pb-3">
						<div class="row">
							<div class="col-lg-3 col-md-4 page-search">
								<input type="search" class="form-control"
								   id="mediaModelSearchKeywordInput"
								   th:placeholder="#{keyword}"
								   oninput="ezyadmin.onKeydownToSearchMedia(this);"
								   onkeydown="ezyadmin.onKeydownToSearchMedia(this);">
							</div>
							<div class="col-lg-3 col-md-4 page-search">
								<select class="form-control" id="mediaModelSearchTypeSelect"
										onchange="ezyadmin.onSearchMediaTypeChanged(this);">
									<option value="">[[#{all_type}]]</option>
									<option th:each="searchMediaType : ${searchMediaTypes}"
											th:value="${searchMediaType}">
										[[#{${searchMediaType.toString().toLowerCase()}}]]
									</option>
								</select>
							</div>
							<div class="col-lg-3 col-md-4 page-search">
								<select class="form-control" id="mediaModelSearchStatusSelect"
										onchange="ezyadmin.onSearchMediaStatusChanged(this);">
									<option value="">[[#{all_status}]]</option>
									<option th:each="searchStatus : ${searchMediaStatuses}"
											th:value="${searchStatus}">
										[[#{${searchStatus.toString().toLowerCase()}}]]
									</option>
								</select>
							</div>
							<div class="col-lg-3 col-md-4 page-search">
								<select class="form-control"
										onchange="ezyadmin.onSearchMediaSortOrderChanged(this);">
									<option value="">[[#{sort_by}]]</option>
									<option th:each="sortOrder : ${searchMediaSortOrders}"
											th:value="${sortOrder}">
										[[#{'sort_by_' + ${sortOrder.toString().toLowerCase()}}]]
									</option>
								</select>
							</div>
						</div>
					</div>
					<div class="text-center">
						<ul class="media-list" id="mediaListBody"></ul>
					</div>
					<div class="d-flex flex-column text-center">
						<span>
							[[#{showing}]]
							<span id="mediaCountText">0</span>
							[[${#strings.toLowerCase(#messages.msg('of'))}]]
							<span id="totalMediaText">0</span>
							[[${#strings.toLowerCase(#messages.msg('media_items'))}]]
						</span>
						<div>
							<button type="button" class="btn btn-primary pl-5 pr-5 mt-2 mb-3 d-none" id="loadMoreMediaButton">
								[[#{load_more}]]
							</button>
						</div>
					</div>
				</div>
			</div>
		</div>
	</div>

	<div class="modal fade pt-4rem" id="add-new-media">
		<div class="modal-dialog modal-md">
			<div class="modal-content">
				<div class="modal-header">
					<h4 class="modal-title">[[#{add_new_media}]]</h4>
					<button type="button" class="close" data-dismiss="modal" aria-label="Close">
						<span aria-hidden="true">&times;</span>
					</button>
				</div>
				<div class="modal-body">
					<form id="addNewMediaForm" method="post" enctype="multipart/form-data">
						<label id="addMediaFileErrorLabel" class="col-form-label text-danger pt-0 d-none" for="addMediaFile">
							<i class="far fa-times-circle"></i> <span class="line-break-anywhere" id="addMediaFileError">[[#{invalid}]]</span>
						</label>
						<div class="input-group">
							<div class="custom-file">
								<input name="file" type="file" id="addMediaFile"
									   class="custom-file-input" multiple>
								<label class="custom-file-label" for="addMediaFile" id="addMediaFileLabel">
									[[#{select_a_file}]]
								</label>
							</div>
						</div>
						<div class="d-flex align-items-center mt-2">
							<input type="checkbox" name="notPublicMedia" id="notPublicMedia" class="form-check wh-1rem">
							<span class="ml-2">[[#{not_public_for_every_user}]]</span>
						</div>
						<div class="d-flex justify-content-center py-4">
							<h5>[[#{or_add_from_url}]]</h5>
						</div>
						<div class="form-group row">
							<label for="addMediaUrlType" class="col-3 col-form-label">
								[[#{type}]] (<span class="text-danger">*</span>):
							</label>
							<div class="col-9">
								<label class="col-form-label text-danger d-none" id="addMediaUrlTypeErrorLabel" for="addMediaUrlType">
									<i class="far fa-times-circle"></i> <span id="addMediaUrlTypeError"></span>
								</label>
								<select name="type" id="addMediaUrlType" class="form-control" aria-label="Type Select"
										onchange="ezyadmin.onAddMediaTypeChanged(this);">
									<option th:each="commonMediaType : ${commonMediaTypes}"
											th:value="${commonMediaType}">
										[[#{${commonMediaType.toString().toLowerCase()}}]]
									</option>
								</select>
							</div>
						</div>
						<div class="form-group row">
							<label for="addMediaUrlName" class="col-3 col-form-label">
								[[#{name}]] (<span class="text-danger">*</span>):
							</label>
							<div class="col-9">
								<label class="col-form-label text-danger d-none" id="addMediaUrlNameErrorLabel" for="addMediaUrlName">
									<i class="far fa-times-circle"></i> <span id="addMediaUrlNameError"></span>
								</label>
								<input type="text" name="originalName" id="addMediaUrlName"
									   class="form-control" th:placeholder="#{name}"
									   onkeydown="ezyadmin.onKeyDownToAddNewMedia()">
							</div>
						</div>
						<div class="form-group row mb-0">
							<label for="addMediaUrlValue" class="col-3 col-form-label">
								[[#{url}]] (<span class="text-danger">*</span>):
							</label>
							<div class="col-9">
								<label class="col-form-label text-danger d-none" id="addMediaUrlValueErrorLabel" for="addMediaUrlValue">
									<i class="far fa-times-circle"></i> <span id="addMediaUrlValueError"></span>
								</label>
								<input type="text" name="url" id="addMediaUrlValue"
									   class="form-control" th:placeholder="#{url}"
									   onkeydown="ezyadmin.onKeyDownToAddNewMedia('add')">
							</div>
						</div>
						<div class="form-group row mt-3 mb-0" id="addMediaUrlDurationWrapper">
							<label for="addMediaUrlDuration" class="col-3 col-form-label">
								[[#{duration}]]
							</label>
							<div class="col-9">
								<label class="col-form-label text-danger d-none" id="addMediaUrlDurationErrorLabel" for="addMediaUrlDuration">
									<i class="far fa-times-circle"></i> <span id="addMediaUrlDurationError"></span>
								</label>
								<input type="text" name="durationInMinutes" id="addMediaUrlDuration"
									   class="form-control" th:placeholder="#{time_in_minutes}"
									   onkeydown="ezyadmin.onKeyDownToAddNewMedia('add')">
							</div>
						</div>
					</form>
				</div>
				<div class="modal-footer justify-content-between">
					<button type="button" class="btn btn-default" data-dismiss="modal">[[#{cancel}]]</button>
					<button type="button" class="btn btn-primary" onclick="ezyadmin.addNewMedias();">[[#{add}]]</button>
				</div>
			</div>
			<!-- /.modal-content -->
		</div>
		<!-- /.modal-dialog -->
	</div>

	<div class="modal fade" id="media-details">
		<div class="modal-dialog modal-xl">
			<div class="modal-content">
				<div class="modal-header">
					<h4 class="modal-title">[[#{media_details}]]</h4>
					<button type="button" class="close" data-dismiss="modal" aria-label="Close">
						<span aria-hidden="true">&times;</span>
					</button>
				</div>
				<div class="modal-body row">
					<div class="col-md-7 col-sm-6 mb-2">
						<div class="text-center max-height-75vn-scroll" id="mediaDetailsBody"></div>
						<div class="d-flex justify-content-center pt-3">
							<button type="button" class="btn btn-outline-secondary"
									onclick="ezyadmin.onReplaceMediaClick();">
								[[#{replace}]]
							</button>
							<button type="button" class="btn btn-outline-danger ml-2" onclick="ezyadmin.deleteMedia();">[[#{delete}]]</button>
							<button type="button" class="btn btn-outline-success ml-2 d-none"
									id="restoreMediaButton" onclick="ezyadmin.restoreMedia();">
								[[#{restore}]]
							</button>
							<a class="btn btn-outline-info ml-2 d-none" id="viewExternalMediaButton" target="_blank">
								[[#{view}]]
								<i class="fas fa-external-link-alt"></i>
							</a>
						</div>
						<input type="file" class="d-none" id="replaceMediaFileInput" onchange="ezyadmin.replaceMedia();">
						<div id="embedMediaScriptArea">
							<span>[[#{embed_script}]]</span>
							<textarea id="embedMediaScript" class="form-control" rows="5"></textarea>
							<div class="d-flex justify-content-center pt-2">
								<button class="btn btn-outline-primary" onclick="ezyadmin.copyEmbedMediaScript();">
									[[#{copy_script}]]
								</button>
							</div>
						</div>
					</div>
					<div class="col-md-5 col-sm-6 bg-light pl-2 pr-2 font-size-95">
						<div class="row">
							<div class="col-12 row">
								<label class="col-4 pr-0">[[#{file_name}]]:</label><span id="fileName" class="col-8 fit-text"></span>
							</div>
							<div class="col-12 row">
								<label class="col-4 pr-0">[[#{file_type}]]:</label><span id="fileType" class="col-8 fit-text"></span>
							</div>
							<div class="col-12 row">
								<label class="col-4 pr-0">[[#{file_size}]]:</label><span id="fileSize" class="col-8"></span>
							</div>
							<div class="col-12 row">
								<label class="col-4 pr-0">[[#{dimension}]]:</label><span id="dimension" class="col-8"></span>
							</div>
							<div class="col-12 row">
								<label class="col-4 pr-0">[[#{upload_by}]]:</label><span id="uploadedBy" class="col-8"></span>
							</div>
							<div class="col-12 row">
								<label class="col-4 pr-0">[[#{upload_on}]]:</label><span id="uploadedOn" class="col-8"></span>
							</div>
						</div>
						<hr class="mt-2 mb-2"/>
						<div class="row">
							<div class="col-12">
								<div class="form-group row mb-1">
									<label for="updateMediaType" class="col-sm-3 col-form-label">[[#{type}]]</label>
									<div class="col-sm-9">
										<label id="updateMediaTypeError" class="col-form-label text-danger d-none" for="updateMediaType">
											<i class="far fa-times-circle"></i>
										</label>
										<select  name="type" id="updateMediaType" class="form-control">
											<option th:each="commonMediaType : ${commonMediaTypes}"
													th:value="${commonMediaType}">
												[[#{${commonMediaType.toString().toLowerCase()}}]]
											</option>
										</select>
									</div>
								</div>
								<div class="form-group row mb-1 d-none" id="updateMediaDurationWrapper">
									<label for="updateMediaDuration" class="col-sm-3 col-form-label">[[#{media_duration}]]</label>
									<div class="col-sm-9">
										<label id="updateMediaDurationErrorLabel" class="col-form-label text-danger d-none" for="updateMediaDuration">
											<i class="far fa-times-circle"></i> <span id="updateMediaDurationError"></span>
										</label>
										<input type="text" name="durationInMinutes" id="updateMediaDuration" class="form-control" th:placeholder="#{media_duration}">
										<span>[[#{time_in_minutes}]]</span>
									</div>
								</div>
								<div class="form-group row mb-1">
									<label for="updateMediaAlternativeText" class="col-sm-3 col-form-label">[[#{alter}]]</label>
									<div class="col-sm-9">
										<label id="updateMediaAlternativeTextErrorLabel" class="col-form-label text-danger d-none" for="updateMediaAlternativeText">
											<i class="far fa-times-circle"></i> <span id="updateMediaAlternativeTextError"></span>
										</label>
										<input type="text" name="alternativeText" id="updateMediaAlternativeText" class="form-control" th:placeholder="#{alternative_text}">
									</div>
								</div>
								<div class="form-group row mb-1">
									<label for="updateMediaTitle" class="col-sm-3 col-form-label">[[#{title}]]</label>
									<div class="col-sm-9">
										<label id="updateMediaTitleErrorLabel" class="col-form-label text-danger d-none" for="updateMediaTitle">
											<i class="far fa-times-circle"></i> <span id="updateMediaTitleError"></span>
										</label>
										<input type="text" name="title" id="updateMediaTitle" class="form-control" th:placeholder="#{title}">
									</div>
								</div>
								<div class="form-group row mb-1">
									<label for="updateMediaCaption" class="col-sm-3 col-form-label">[[#{caption}]]</label>
									<div class="col-sm-9">
										<label id="updateMediaCaptionErrorLabel" class="col-form-label text-danger d-none" for="updateMediaCaption">
											<i class="far fa-times-circle"></i> <span id="updateMediaCaptionError"></span>
										</label>
										<textarea name="caption" id="updateMediaCaption" class="form-control" th:placeholder="#{caption}"></textarea>
									</div>
								</div>
								<div class="form-group row mb-1">
									<label for="updateMediaDescription" class="col-sm-3 col-form-label">[[#{description}]]</label>
									<div class="col-sm-9">
										<label id="updateMediaDescriptionErrorLabel" class="col-form-label text-danger d-none" for="updateMediaDescription">
											<i class="far fa-times-circle"></i> <span id="updateMediaDescriptionError"></span>
										</label>
										<textarea name="description" id="updateMediaDescription" class="form-control" th:placeholder="#{description}"></textarea>
									</div>
								</div>
								<div class="form-group row mb-1">
									<label for="updateNotPublicMedia" class="col-sm-3 col-form-label"></label>
									<div class="col-sm-9 d-flex align-items-center">
										<input type="checkbox" name="notPublicMedia" id="updateNotPublicMedia" class="form-check">
										<span class="ml-2">[[#{not_public_for_every_user}]]</span>
									</div>
								</div>
								<div class="form-group row mb-1">
									<label for="updateMediaUrl" class="col-sm-3 col-form-label">[[#{media_url}]]</label>
									<div class="col-sm-9">
										<label class="col-form-label text-danger d-none" id="updateMediaUrlErrorLabel" for="updateMediaUrl">
											<i class="far fa-times-circle"></i> <span id="updateMediaUrlError"></span>
										</label>
										<input type="text" name="mediaUrl" id="updateMediaUrl"
											   class="form-control" th:placeholder="#{media_url}">
									</div>
								</div>
								<div class="form-group row">
									<div class="col-sm-3"></div>
									<div class="col-lg-4 col-md-9 pt-sm-0 pt-1" th:if="${currentMenu == 'media'}">
										<button type="button" class="btn btn-primary w-100 white-space-nowrap"
												onclick="ezyadmin.copyMediaUrl();">
											[[#{copy_url}]]
										</button>
									</div>
									<div class="col-lg-4 col-md-9 pt-sm-0 pt-1" th:if="${currentMenu != 'media'}">
										<button type="button" class="btn btn-primary w-100" id="selectMediaButton"
												onclick="ezyadmin.selectMedia();">
											[[#{select}]]
										</button>
									</div>
									<div class="d-lg-none d-md-block col-md-3 d-none"></div>
									<div class="col-lg-4 col-md-9 pt-lg-0 pt-md-1 pt-1">
										<button type="button" class="btn btn-outline-primary w-100 text-primary-always"
												onclick="ezyadmin.updateMedia();">[[#{update}]]</button>
									</div>
									<div class="col-lg-1"></div>
								</div>
							</div>
						</div>
					</div>
				</div>
			</div>
			<!-- /.modal-content -->
		</div>
		<!-- /.modal-dialog -->
	</div>
	<!-- /.modal -->
</th:block>
<script th:fragment="scripts" th:inline="javascript">
/*<![CDATA[*/
ezyadmin.numberOfMediaPerPage = /*[[${numberOfMediaPerPage}]]*/;
ezyadmin.messages.administrator = /*[[#{administrator}]]*/;
ezyadmin.messages.script = /*[[#{script}]]*/;
ezyadmin.messages.delete_successfully = /*[[#{delete_successfully}]]*/;
ezyadmin.messages.delete_failed = /*[[#{delete_failed}]]*/;
ezyadmin.messages.update_successfully = /*[[#{update_successfully}]]*/;
ezyadmin.messages.update_failed = /*[[#{update_failed}]]*/;
ezyadmin.messages.user = /*[[#{user}]]*/;
ezyadmin.accessibleUris['/api/v1/media/list'] = /*[[${adminRoles.isAccessible('/api/v1/media/list')}]]*/;
ezyadmin.accessibleUris['/api/v1/media/{name}'] = /*[[${adminRoles.isAccessible('/api/v1/media/{name}')}]]*/;
ezyadmin.accessibleUris['/api/v1/media/{id}/details'] = /*[[${adminRoles.isAccessible('/api/v1/media/{id}/details')}]]*/;
ezyadmin.accessibleUris['/api/v1/media/{id}/edit'] = /*[[${adminRoles.isAccessible('/api/v1/media/{id}', 'PUT')}]]*/;
ezyadmin.accessibleUris['/api/v1/media/{id}/delete'] = /*[[${adminRoles.isAccessible('/api/v1/media/{id}', 'DELETE')}]]*/;
ezyadmin.accessibleUris['/api/v1/media/{id}/replace'] = /*[[${adminRoles.isAccessible('/api/v1/media/{id}/replace', 'POST')}]]*/;
ezyadmin.accessibleUris['/api/v1/media/{id}/restore'] = /*[[${adminRoles.isAccessible('/api/v1/media/{id}/restore', 'PUT')}]]*/;
/*]]>*/

$('#media-details').on('hidden.bs.modal', function (e) {
	var items = $('.playable-media-item');
	for(var i = 0 ; i < items.length ; ++i) {
		items[i].pause();
	}
})

ezyadmin.mediaSelectedHandlers = {};
ezyadmin.showMediaModal = function(command) {
	ezyadmin.mediaCount = 0;
	ezyadmin.mediaTotal = 0;
	ezyadmin.lastNextPageToken = '';
	ezyadmin.searchMediaKeyword = '';
	ezyadmin.searchMediaType = '';
	ezyadmin.searchMediaStatus = '';
	$('#mediaModelSearchKeywordInput').val('');
	$('#mediaModelSearchTypeSelect').val('');
	$('#mediaModelSearchStatusSelect').val('');
	$('#mediaListBody').html('');
	ezyadmin.fetchMediaList(true);
	$('#media-modal').modal('show');
	var handler = {};
	handler.onMediaShow = function (callback) {
		handler.showCallback = callback;
		return handler;
	}
	handler.onMediaSelected = function (callback) {
		handler.selectCallback = callback;
		return handler;
	}
	handler.onMultipleMediaSelected = function (callback) {
		handler.selectMultipleCallback = callback;
		return handler;
	}
	var actualCommand = command || '';
	ezyadmin.mediaSelectedHandlers[actualCommand] = handler;
	ezyadmin.currentMediaSelectedCommand = actualCommand;
	return handler;
}

ezyadmin.closeMediaModal = function() {
	$('#media-modal').modal('hide');
	$('#media-details').modal('hide');
}

ezyadmin.selectMedia = function() {
	ezyadmin.mediaSelectedHandlers[ezyadmin.currentMediaSelectedCommand]?.selectCallback(ezyadmin.selectedMedia);
}

// ========== add new =============
ezyadmin.addMediaView = {
    name: 'addMedia',
    chooseFileLabelText: $('#addMediaFileLabel').text()
};
bsCustomFileInput.init();

$(document).ready(() => {
	$('#addMediaFile').on('click', function() {
    	$(this).val('');
	});
});

ezyadmin.showAddNewMediaModal = function() {
	ezyadmin.resetFormData({
		addMediaUrlName: true,
		addMediaUrlValue: true,
		addMediaUrlDuration: true
	});
	$('#addMediaFileErrorLabel').addClass('d-none');
	$('#notPublicMedia').prop('checked', false);
	$('#add-new-media').modal('show');
}

ezyadmin.onAddMediaTypeChanged = function(e) {
	var mediaType = $(e).val();
	if (mediaType == 'VIDEO' || mediaType == 'AUDIO') {
		$('#addMediaUrlDurationWrapper').removeClass('d-none');
	} else {
		$('#addMediaUrlDurationWrapper').addClass('d-none');
	}
}

ezyadmin.addNewMedias = function() {
	$('#fileErrorLabel').addClass('d-none');
	var notPublicMedia = $('#notPublicMedia').prop('checked');
    $.each($('#addMediaFile')[0].files, function(index, file) {
        ezyadmin.addNewMedia(file, notPublicMedia);
    });
    var formData = ezyadmin.formDataToObject('addNewMediaForm');
    delete formData.file;
    if (formData.url.trim()) {
		ezyadmin.addNewMediaFromUrl(formData, notPublicMedia);
    }
}

ezyadmin.addNewMediaAsync = function(file, notPublicMedia, options) {
    return new Promise((resolve, reject) => {
        ezyadmin.addNewMedia(file, notPublicMedia, {
            ...options,
            onSuccess: (media) => resolve(media),
            onFailed: (e) => reject(e)
        });
    });
};

ezyadmin.addNewMedia = function(file, notPublicMedia, options) {
	ezyadmin.showLoadingScreen({showPercent: true});
    var data = new FormData();
    data.append('file', file);
    $.ajax({
        type: "POST",
        enctype: 'multipart/form-data',
        url: "/api/v1/media/add?notPublic=" + notPublicMedia,
        data: data,
        processData: false,
        contentType: false,
        cache: false,
        xhr: function () {
            var xhr = new window.XMLHttpRequest();
            xhr.upload.addEventListener('progress', function(event) {
                if (event.lengthComputable) {
                    var percentComplete = Math.round((event.loaded / event.total) * 100);
                    ezyadmin.setLoadingScreenPercent(percentComplete);
                }
            });
            return xhr;
        },
        success: function (data) {
            $('#add-new-media').modal('hide');
            $('#addMediaFileLabel').text(ezyadmin.addMediaView.chooseFileLabelText);
            var media = JSON.parse(data);
            ezyadmin.mediaById[media.id] = media;
            ezyadmin.appendToMediaListTable([media], true);
            $('#mediaCountText').text(++ ezyadmin.mediaCount);
            $('#totalMediaText').text(++ ezyadmin.mediaTotal);
            ezyadmin.setLoadingScreenPercent(100);
            ezyadmin.hideLoadingScreen();
            var onSuccess = options?.onSuccess;
            if (onSuccess) {
				onSuccess(media);
            }
        },
        error: function(e) {
            ezyadmin.processUploadFileApiErrors(e, ezyadmin.addMediaView);
            ezyadmin.hideLoadingScreen();
            var onFailed = options?.onFailed;
            if (onFailed) {
            	onFailed(e);
            }
        }
    });
}

ezyadmin.onKeyDownToAddNewMedia = function() {
	if(event.key === 'Enter') {
		var notPublicMedia = $('#notPublicMedia').prop('checked');
		var formData = ezyadmin.formDataToObject('addNewMediaForm');
		delete formData.file;
		ezyadmin.addNewMediaFromUrl(formData, notPublicMedia);
    }
}

ezyadmin.addNewMediaFromUrl = function(formData, notPublicMedia) {
	var mediaType = formData.type;
	formData.saveDuration = mediaType == 'VIDEO' || mediaType == 'AUDIO';
    $.ajax({
        type: "POST",
        url: "/api/v1/media/add-from-url?notPublic=" + notPublicMedia,
        contentType: 'application/json',
        data: JSON.stringify(formData),
        success: function (media) {
            $('#add-new-media').modal('hide');
            ezyadmin.mediaById[media.id] = media;
            ezyadmin.appendToMediaListTable([media], true);
            $('#mediaCountText').text(++ ezyadmin.mediaCount);
            $('#totalMediaText').text(++ ezyadmin.mediaTotal);
        },
        error: function(e) {
        	var formView = {
        		addMediaUrlName: true,
        		addMediaUrlValue: true,
        		addMediaUrlDuration: true
        	};
        	var errors = e.responseJSON || {};
        	errors.addMediaUrlName = errors.originalName;
			errors.addMediaUrlValue = errors.url;
			errors.addMediaUrlDuration = errors.durationInMinutes;
            ezyadmin.processUpdateApiErrors(formView, e);
        }
    });
}

// =============== search media ==========
ezyadmin.onKeydownToSearchMedia = function(e) {
	ezyadmin.searchMediaKeyword = $(e).val();
	if(event.key === 'Enter' || !ezyadmin.searchMediaKeyword) {
		ezyadmin.fetchMediaList(true);
    }
}

ezyadmin.onSearchMediaTypeChanged = function(e) {
	ezyadmin.searchMediaType = $(e).val();
	ezyadmin.fetchMediaList(true);
}

ezyadmin.onSearchMediaStatusChanged = function(e) {
	ezyadmin.searchMediaStatus = $(e).val();
	ezyadmin.fetchMediaList(true);
}

ezyadmin.onSearchMediaSortOrderChanged = function(e) {
	ezyadmin.searchMediaSortOrder = $(e).val();
	ezyadmin.fetchMediaList(true);
}

// ========== media list =============
ezyadmin.mediaCount = 0;
ezyadmin.mediaTotal = 0;
ezyadmin.mediaById = {};
ezyadmin.fetchMediaList = function(replace) {
	var url = ezyadmin.accessibleUris['/api/v1/media/list']
		? '/api/v1/media/list'
		: '/api/v1/me/media/list';
	url += '?limit=' + ezyadmin.numberOfMediaPerPage;
	if (ezyadmin.searchMediaKeyword) {
		url += '&keyword=' + ezyadmin.searchMediaKeyword;
	}
	if (ezyadmin.searchMediaType) {
		url += '&type=' + ezyadmin.searchMediaType;
	}
	if (ezyadmin.searchMediaStatus) {
		url += '&status=' + ezyadmin.searchMediaStatus;
	}
	if (ezyadmin.searchMediaSortOrder) {
		url += '&sortOrder=' + ezyadmin.searchMediaSortOrder;
	}
	if (replace) {
		ezyadmin.lastNextPageToken = null;
	}
    $.ajax({
        type: "GET",
        url: url + (ezyadmin.lastNextPageToken
        	? '&nextPageToken=' + ezyadmin.lastNextPageToken
        	: ''),
        success: function(data) {
            ezyadmin.appendToMediaListTable(data.items, false, replace);
            ezyadmin.mediaCount = replace
            	? data.count
            	: ezyadmin.mediaCount + data.count;
            ezyadmin.mediaTotal = data.total;
            data.items.forEach((item) => {
				ezyadmin.mediaById[item.id] = item;
            });
            $('#mediaCountText').text(ezyadmin.mediaCount);
            $('#totalMediaText').text(ezyadmin.formatTotalResults(data.total));
            ezyadmin.lastNextPageToken = data.pageToken.next;
            if (data.continuation.hasNext) {
                $('#loadMoreMediaButton').removeClass('d-none');
            } else {
            	$('#loadMoreMediaButton').addClass('d-none');
            }
        },
        error: function(data, e) {
            ezyadmin.processGetApiErrors(data);
        }
    });
}

ezyadmin.appendToMediaListTable = function(mediaList, toHead, replace) {
    var html = ezyadmin.buildMediaListBodyHtml(mediaList);
    var mediaListBody = $('#mediaListBody');
    if (replace) {
    	mediaListBody.html(html);
    } else {
    	mediaListBody.html(toHead ? html + mediaListBody.html() : mediaListBody.html() + html);
    }
}

ezyadmin.buildMediaListBodyHtml = function(mediaList) {
    var html = '';
    mediaList.forEach((media) => {
    	var replaced = ezyadmin.replacedMediaById[media.id];
    	var mediaUrl = ezyadmin.extractMediaUrl(media);
    	if (replaced) {
    		mediaUrl = ezyadmin.extractMediaUrlAddNowAsVersion(media);
    	}
    	var internalMedia = ezyadmin.isInternalMediaUrl(mediaUrl);
        html += `
			<li id="mediaItem${media.id}" role="button"
				onclick="ezyadmin.showMediaDetails(${media.id});"
				onmouseover="ezyadmin.onMediaMouseOver(this, ${media.id});">
				${media.type === 'IMAGE' || media.type === 'AVATAR' ? `
					<img src="${mediaUrl}" alt="${media.originalName}" class="wh-150px img-thumbnail">
					<span class="text-danger delete-button" aria-hidden="true" onclick="ezyadmin.onFastDeleteMediaClick(${media.id});">&times;</span>
					<input type="checkbox" name="mediaItemCheckbox" class="media-item-checkbox" onclick="ezyadmin.onMediaItemCheckboxClick(this, ${media.id})">
				` : (media.type === 'VIDEO' && internalMedia) ? `
					<video class="video-thumbnail">
						<source src="${mediaUrl}" type="video/mp4">
						<source src="${mediaUrl}" type="video/ogg">
						Your browser does not support the video tag.
					</video>
					<span class="text-danger delete-button" aria-hidden="true" onclick="ezyadmin.onFastDeleteMediaClick(${media.id});">&times;</span>
					<input type="checkbox" name="mediaItemCheckbox" class="media-item-checkbox video-item-checkbox" onclick="ezyadmin.onMediaItemCheckboxClick(this, ${media.id})">
				` : (media.type === 'AUDIO' && internalMedia) ? `
					<div class="d-flex justify-content-center">
						<div class="file-thumbnail audio-thumbnail">
							<audio controls>
								<source src="${mediaUrl}" type="audio/mpeg">
								<source src="${mediaUrl}" type="audio/ogg">
								Your browser does not support the audio tag.
							</audio>
							<span class="text-dark-always">${media.originalName}</span>
						</div>
						<span class="text-danger delete-button" aria-hidden="true" onclick="ezyadmin.onFastDeleteMediaClick(${media.id});">&times;</span>
						<input type="checkbox" name="mediaItemCheckbox" class="media-item-checkbox" onclick="ezyadmin.onMediaItemCheckboxClick(this, ${media.id})">
					</div>
				` : `
					<div class="d-flex justify-content-center">
						<div class="file-thumbnail">
							<i class="far fa-file text-dark-always"></i>
							<div><span class="text-dark-always">${media.originalName}</span></div>
						</div>
						<span class="text-danger delete-button" aria-hidden="true" onclick="ezyadmin.onFastDeleteMediaClick(${media.id});">&times;</span>
						<input type="checkbox" name="mediaItemCheckbox" class="media-item-checkbox" onclick="ezyadmin.onMediaItemCheckboxClick(this, ${media.id})">
					</div>
				`}
			</li>`;
    });
    return html;
}

$('#loadMoreMediaButton').on('click', (e) => {
    ezyadmin.fetchMediaList();
});

// ======================= media details =============
ezyadmin.selectedMediaId = 0;
ezyadmin.showMediaDetails = function(mediaId) {
    ezyadmin.selectedMediaId = mediaId;
    ezyadmin.fetchMediaDetailsById(mediaId);
}

ezyadmin.copyMediaUrl = function() {
    ezyadmin.copyToClipboard('updateMediaUrl', true, 'URL');
}

ezyadmin.copyEmbedMediaScript = function() {
    ezyadmin.copyToClipboard(
    	'embedMediaScript',
    	true,
    	ezyadmin.messages.script
	);
}

ezyadmin.isInternalMediaUrl = function(mediaUrl) {
	return mediaUrl
		&& !mediaUrl.startsWith('http://')
		&& !mediaUrl.startsWith('https://');
}

ezyadmin.isExternalMediaUrl = function(mediaUrl) {
	return mediaUrl
		&& (mediaUrl.startsWith('http://')
		|| mediaUrl.startsWith('https://'));
}

ezyadmin.fetchMediaDetailsById = function(mediaId, replace) {
	var url = ezyadmin.accessibleUris['/api/v1/media/{id}/details']
		? '/api/v1/media/' + mediaId + '/details'
		: '/api/v1/me/media/' + mediaId + '/details';
	$.ajax({
        url: url,
        type: 'GET',
        dataType: 'json'
    })
    .done(function(media) {
        ezyadmin.selectedMedia = media;
        var uploadedByHtml = '';
		if (media.ownerAdmin) {
			var profileUrl = `/admins/${media.ownerAdmin.username}${ezyadmin.lang ? `?lang=${ezyadmin.lang}` : ''}`;
			uploadedByHtml = `<a href="${profileUrl}">${media.ownerAdmin.name} (${ezyadmin.messages.administrator.toLowerCase()})</a>`;
		} else if (media.ownerUser) {
			var profileUrl = `/users/${media.ownerUser.username}${ezyadmin.lang ? `?lang=${ezyadmin.lang}` : ''}`;
			uploadedByHtml = `<a href="${profileUrl}">${media.ownerUser.name} (${ezyadmin.messages.user.toLowerCase()})</a>`;
		}
		$('#uploadedBy').html(uploadedByHtml);

		var mediaDetailsBodyHtml = '';
		var mediaUrl = replace
			? ezyadmin.extractMediaUrlAddNowAsVersion(media)
			: ezyadmin.extractMediaUrl(media);
		if (media.type === 'IMAGE' || media.type === 'AVATAR') {
			mediaDetailsBodyHtml = `<img src="${mediaUrl}" alt="${media.alternativeText}" class="img-fluid">`;
		} else if (media.type === 'VIDEO') {
			mediaDetailsBodyHtml = `
				<video class="video-details playable-media-item" controls>
					<source src="${mediaUrl}" type="video/mp4">
					<source src="${mediaUrl}" type="video/ogg">
					Your browser does not support the video tag.
				</video>`;
		} else if (media.type === 'AUDIO') {
			mediaDetailsBodyHtml = `
				<div class="file-details audio-details">
					<audio class="playable-media-item" controls>
						<source src="${mediaUrl}" type="audio/mpeg">
						<source src="${mediaUrl}" type="audio/ogg">
						Your browser does not support the audio tag.
					</audio>
					<span class="text-dark-always">${media.originalName}</span>
				</div>`;
		} else {
			mediaDetailsBodyHtml = `
				<div class="file-details">
					<i class="far fa-file text-dark-always"></i>
					<div>
						<a class="text-dark-always" href="${mediaUrl}" target="_blank">${media.originalName}</a>
					</div>
				</div>`;
		}

		var webMediaUrl = ezyadmin.extractMediaUrl(media);
		if (ezyadmin.isInternalMediaUrl(mediaUrl)) {
			webMediaUrl = ezyadmin.webUrl + mediaUrl;
		}
		if (media.type === 'VIDEO') {
			$('#embedMediaScript').val(`
				<iframe width="560" height="315"
					src="${mediaUrl}"
					title="Video player" frameborder="0"
					allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share"
					allowfullscreen>
				</iframe>`);
			$('#embedMediaScriptArea').removeClass('d-none');
		} else {
			$('#embedMediaScriptArea').addClass('d-none');
		}
		$('#mediaDetailsBody').html(mediaDetailsBodyHtml);
		$('#uploadedOn').text(ezyadmin.formatTimeStamp(media.createdAt));
		$('#fileName').text(media.originalName);
		$('#fileType').text(media.mimeType);
		$('#updateMediaUrl').val(webMediaUrl);
		$('#media-details').modal('show');
		$('#fileSize').text(ezyadmin.toCapacityString(media.size));
		$('#dimension').text(media.width + 'x' + media.height);
		$('#updateMediaType').val(media.type);
		if (ezyadmin.isExternalMediaUrl(mediaUrl)) {
			$('#updateMediaDuration').val(media.durationInMinutes);
			$('#updateMediaDurationWrapper')
				.removeClass('d-none');
			$('#viewExternalMediaButton')
				.attr('href', mediaUrl)
				.removeClass('d-none');
		} else {
			$('#updateMediaDurationWrapper').addClass('d-none');
			$('#viewExternalMediaButton').addClass('d-none');
		}
		$('#updateMediaAlternativeText').val(media.alternativeText);
		$('#updateMediaTitle').val(media.title);
		$('#updateMediaCaption').val(media.caption);
		$('#updateMediaDescription').val(media.description);
		$('#updateNotPublicMedia').prop('checked', !media.publicMedia)
		if (media.status === 'REMOVED') {
			$('#restoreMediaButton').removeClass('d-none');
		} else {
			$('#restoreMediaButton').addClass('d-none');
		}
		$('#selectMediaButton').attr('disabled', false);
		var handler = ezyadmin.mediaSelectedHandlers[ezyadmin.currentMediaSelectedCommand];
		if (handler) {
			var showCallback = handler.showCallback;
			if (showCallback) {
				showCallback(ezyadmin.selectedMedia);
			}
		}
    })
    .fail(function(e) {
    	ezyadmin.processGetApiErrors(e);
    });
}

// ======================= media update =============
ezyadmin.updateMedia = function() {
	var url = $('#updateMediaUrl').val();
	if (url && url.startsWith(ezyadmin.webUrl)) {
		url = url.slice(ezyadmin.webUrl.length);
	}
    var updateMediaData = {
    	type: $('#updateMediaType').val(),
        alternativeText: $('#updateMediaAlternativeText').val(),
        title: $('#updateMediaTitle').val(),
        caption: $('#updateMediaCaption').val(),
        description: $('#updateMediaDescription').val(),
        url: url,
        notPublic: $('#updateNotPublicMedia').prop('checked')
    };
    if (ezyadmin.isExternalMediaUrl(updateMediaData.url)) {
		updateMediaData.updateDuration = true;
		updateMediaData.durationInMinutes = $('#updateMediaDuration').val();
	}
    var url = ezyadmin.accessibleUris['/api/v1/media/{id}/edit']
    	? '/api/v1/media/' + ezyadmin.selectedMediaId
    	: '/api/v1/me/media/' + ezyadmin.selectedMediaId;
    $.ajax({
        type: "PUT",
        url: url,
        contentType: 'application/json',
        data: JSON.stringify(updateMediaData),
        success: function (data) {
            ezyadmin.shortToast('bg-success', ezyadmin.messages.update_successfully);
            ezyadmin.fetchMediaDetailsById(ezyadmin.selectedMediaId);
            ezyadmin.fetchMediaList(true);
        },
        error: function (e) {
           ezyadmin.shortToast('bg-danger', ezyadmin.messages.update_failed);
           var formView = {
        		updateMediaDuration: true,
        		updateMediaAlternativeText: true,
        		updateMediaTitle: true,
        		updateMediaCaption: true,
        		updateMediaDescription: true,
        		updateMediaUrl: true
        	};
        	var errors = e.responseJSON || {};
        	errors.updateMediaDuration = errors.durationInMinutes;
			errors.updateMediaAlternativeText = errors.alternativeText;
			errors.updateMediaTitle = errors.title;
			errors.updateMediaCaption = errors.caption;
			errors.updateMediaDescription = errors.description;
			errors.updateMediaUrl = errors.url;
			ezyadmin.processUpdateApiErrors(formView, e);
        }
    });
}

// ======================= media update =============
ezyadmin.onReplaceMediaClick = function() {
	$('#replaceMediaFileInput').val('');
	$('#replaceMediaFileInput').trigger('click');
}

ezyadmin.replacedMediaById = {};
ezyadmin.replaceMedia = function() {
	var fileInput = $('#replaceMediaFileInput')[0];
	if (!fileInput.files || !fileInput.files.length) {
		return;
	}
	var mediaId = ezyadmin.selectedMediaId;
	var data = new FormData();
	data.append('file', fileInput.files[0]);
	ezyadmin.showLoadingScreen({showPercent: true});
	var url = ezyadmin.accessibleUris['/api/v1/media/{id}/replace']
		? '/api/v1/media/' + mediaId + '/replace'
		: '/api/v1/me/media/' + mediaId + '/replace';
	$.ajax({
		type: "POST",
		enctype: 'multipart/form-data',
		url: url,
		data: data,
		processData: false,
		contentType: false,
		cache: false,
		xhr: function () {
			var xhr = new window.XMLHttpRequest();
			xhr.upload.addEventListener('progress', function(event) {
				if (event.lengthComputable) {
					var percentComplete = Math.round((event.loaded / event.total) * 100);
					ezyadmin.setLoadingScreenPercent(percentComplete);
				}
			});
			return xhr;
		},
		success: function (data) {
			ezyadmin.setLoadingScreenPercent(100);
			ezyadmin.hideLoadingScreen();
			ezyadmin.fetchMediaDetailsById(mediaId, true);
			ezyadmin.replacedMediaById[mediaId] = data;
			ezyadmin.fetchMediaList(true);
		},
		error: function (e) {
			ezyadmin.hideLoadingScreen();
			ezyadmin.shortToast('bg-danger', ezyadmin.messages.update_failed);
		}
	});
}

// ======================= media delete =============

ezyadmin.onFastDeleteMediaClick = function(mediaId) {
	ezyadmin.deleteMedia(mediaId);
	window.event.stopPropagation();
}

ezyadmin.deleteMedia = function(mediaId) {
	var actualMediaId = (mediaId || ezyadmin.selectedMediaId);
	var url = ezyadmin.accessibleUris['/api/v1/media/{id}/delete']
    	? '/api/v1/media/' + actualMediaId
    	: '/api/v1/me/media/' + actualMediaId;
     $.ajax({
        type: "DELETE",
        url: url,
        success: function (data) {
            ezyadmin.shortToast('bg-success', ezyadmin.messages.delete_successfully);
            $('#media-details').modal('hide');
            $('#mediaItem' + actualMediaId).remove();
            $('#mediaCountText').text(-- ezyadmin.mediaCount);
            $('#totalMediaText').text(-- ezyadmin.mediaTotal);
        },
        error: function (data, e) {
           ezyadmin.shortToast('bg-danger', ezyadmin.messages.delete_failed);
        }
    });
}

// ======================= media restore =============
ezyadmin.restoreMedia = function(mediaId) {
	var actualMediaId = (mediaId || ezyadmin.selectedMediaId);
	var url = ezyadmin.accessibleUris['/api/v1/media/{id}/restore']
    	? '/api/v1/media/' + actualMediaId + '/restore'
    	: '/api/v1/me/media/' + actualMediaId + '/restore';
     $.ajax({
        type: "PUT",
        url: url,
        success: function (data) {
            ezyadmin.shortToast('bg-success', ezyadmin.messages.update_successfully);
            ezyadmin.fetchMediaDetailsById(actualMediaId);
            ezyadmin.fetchMediaList(true);
        },
        error: function (data, e) {
           ezyadmin.shortToast('bg-danger', ezyadmin.messages.update_failed);
        }
    });
}

// ================ media checkbox ===========
ezyadmin.checkedMediaItemIds = [];
ezyadmin.onMediaItemCheckboxClick = function(e, mediaId) {
	window.event.stopPropagation();
	var checked = $(e).prop('checked');
	if (checked) {
		if (ezyadmin.checkedMediaItemIds.indexOf(mediaId) < 0) {
			ezyadmin.checkedMediaItemIds.push(mediaId);
		}
	} else {
		ezyadmin.removeItemFromList(ezyadmin.checkedMediaItemIds, mediaId);
	}
	if (ezyadmin.checkedMediaItemIds.length) {
		$('#selectMediasButton').removeClass('d-none');
	} else {
		$('#selectMediasButton').addClass('d-none');
	}
}

ezyadmin.defaultHandleSelectedMediaIds = function() {
	ezyadmin.selectedMediaList = [];
	ezyadmin.checkedMediaItemIds.forEach((checkedMediaId) => {
		var selectedMedia = ezyadmin.mediaById[checkedMediaId];
		if (selectedMedia) {
			ezyadmin.selectedMediaList.push(selectedMedia);
		}
	});
	var handler = ezyadmin.mediaSelectedHandlers[ezyadmin.currentMediaSelectedCommand];
	if (handler && handler.selectMultipleCallback) {
		handler.selectMultipleCallback(ezyadmin.selectedMediaList);
	} else {
		ezyadmin.selectedMediaList.forEach((checkedMedia) => {
			ezyadmin.selectedMedia = checkedMedia;
			ezyadmin.selectMedia();
		});
	}
	ezyadmin.checkedMediaItemIds = [];
	ezyadmin.selectedMediaList = [];
}

ezyadmin.onSelectMediasButtonClicked = function() {
	if (ezyadmin.handleSelectedMediaIds) {
		ezyadmin.handleSelectedMediaIds(ezyadmin.checkedMediaItemIds);
	} else {
		ezyadmin.defaultHandleSelectedMediaIds();
	}
	ezyadmin.closeMediaModal();
}

// ================ drag drop to add ===========
$(document).ready(function () {
    var mediaListBody = $('#mediaListBody');

    mediaListBody.on('dragover', function (e) {
        e.preventDefault();
        e.stopPropagation();
        $(this).addClass('dragover');
    });

    mediaListBody.on('dragleave', function (e) {
        e.preventDefault();
        e.stopPropagation();
        $(this).removeClass('dragover');
    });

    mediaListBody.on('drop', function (e) {
        e.preventDefault();
        e.stopPropagation();
        $(this).removeClass('dragover');

        var files = e.originalEvent.dataTransfer.files;
        for (var i = 0; i < files.length; i++) {
            ezyadmin.addNewMedia(files[i], false);
        }
    });
});

// ================== hover ===============
$(document).ready(function(){
	$(document).mousedown(function(event) {
		if (event.which === 1) {
			ezyadmin.isMouseDown = true;
		}
	});

	$(document).mouseup(function(event) {
		if (event.which === 1) { // Left mouse button
			ezyadmin.isMouseDown = false;
		}
	});
});
ezyadmin.onMediaMouseOver = function(e, mediaId) {
	if (ezyadmin.isMouseDown) {
		if (ezyadmin.checkedMediaItemIds.indexOf(mediaId) < 0) {
			ezyadmin.checkedMediaItemIds.push(mediaId);
		}
		var checkbox = $(e).find(".media-item-checkbox");
		checkbox.attr("checked", true);
		$('#selectMediasButton').removeClass('d-none');
	}
}
</script>
</body>
</html>
