/*
 * Copyright (c) 2015
 *
 * This file is licensed under the Affero General Public License version 3
 * or later.
 *
 * See the COPYING-README file.
 *
 */

/* globals Clipboard, Handlebars */

(function() {
	if (!OC.Share) {
		OC.Share = {};
	}

	var PASSWORD_PLACEHOLDER = '**********';
	var PASSWORD_PLACEHOLDER_MESSAGE = t('core', 'Choose a password for the public link');
	var PASSWORD_PLACEHOLDER_MESSAGE_OPTIONAL = t('core', 'Choose a password for the public link or press the "Enter" key');

	/**
	 * @class OCA.Share.ShareDialogLinkShareView
	 * @member {OC.Share.ShareItemModel} model
	 * @member {jQuery} $el
	 * @memberof OCA.Sharing
	 * @classdesc
	 *
	 * Represents the GUI of the share dialogue
	 *
	 */
	var ShareDialogLinkShareView = OC.Backbone.View.extend({
		/** @type {string} **/
		id: 'shareDialogLinkShare',

		/** @type {OC.Share.ShareConfigModel} **/
		configModel: undefined,

		/** @type {boolean} **/
		showLink: true,

		/** @type {boolean} **/
		showPending: false,

		/** @type {string} **/
		password: '',

		/** @type {string} **/
		newShareId: 'new-share',

		events: {
			// open menu
			'click .share-menu .icon-more': 'onToggleMenu',
			// hide download
			'change .hideDownloadCheckbox': 'onHideDownloadChange',
			// password
			'click input.share-pass-submit': 'onPasswordEntered', 
			'keyup input.linkPassText': 'onPasswordKeyUp', // check for the enter key
			'change .showPasswordCheckbox': 'onShowPasswordClick',
			'change .passwordByTalkCheckbox': 'onPasswordByTalkChange',
			'change .publicEditingCheckbox': 'onAllowPublicEditingChange',
			// copy link url
			'click .linkText': 'onLinkTextClick',
			// social
			'click .pop-up': 'onPopUpClick',
			// permission change
			'change .publicUploadRadio': 'onPublicUploadChange',
			// expire date
			'click .expireDate' : 'onExpireDateChange',
			'change .datepicker': 'onChangeExpirationDate',
			'click .datepicker' : 'showDatePicker',
			// note
			'click .share-add': 'showNoteForm',
			'click .share-note-delete': 'deleteNote',
			'click .share-note-submit': 'updateNote',
			// remove
			'click .unshare': 'onUnshare',
			// new share
			'click .new-share': 'newShare',
			// enforced pass set
			'submit .enforcedPassForm': 'enforcedPasswordSet',
		},

		initialize: function(options) {
			var view = this;

			this.model.on('change:permissions', function() {
				view.render();
			});

			this.model.on('change:itemType', function() {
				view.render();
			});

			this.model.on('change:allowPublicUploadStatus', function() {
				view.render();
			});

			this.model.on('change:hideFileListStatus', function() {
				view.render();
			});

			this.model.on('change:linkShares', function(model, linkShares) {
				// The "Password protect by Talk" item is shown only when there
				// is a password. Unfortunately there is no fine grained
				// rendering of items in the link shares, so the whole view
				// needs to be rendered again when the password of a share
				// changes.
				// Note that this event handler is concerned only about password
				// changes; other changes in the link shares does not trigger
				// a rendering, so the view must be rendered again as needed in
				// those cases (for example, when a link share is removed).
				
				var previousLinkShares = model.previous('linkShares');
				if (previousLinkShares.length !== linkShares.length) {
					return;
				}

				var i;
				for (i = 0; i < linkShares.length; i++) {
					if (linkShares[i].id !== previousLinkShares[i].id) {
						// A resorting should never happen, but just in case.
						return;
					}

					if (linkShares[i].password !== previousLinkShares[i].password) {
						view.render();

						return;
					}
				}
			});

			if(!_.isUndefined(options.configModel)) {
				this.configModel = options.configModel;
			} else {
				throw 'missing OC.Share.ShareConfigModel';
			}

			var clipboard = new Clipboard('.clipboard-button');
			clipboard.on('success', function(e) {
				var $trigger = $(e.trigger);

				$trigger.tooltip('hide')
					.attr('data-original-title', t('core', 'Copied!'))
					.tooltip('fixTitle')
					.tooltip({placement: 'bottom', trigger: 'manual'})
					.tooltip('show');
				_.delay(function() {
					$trigger.tooltip('hide')
						.attr('data-original-title', t('core', 'Copy link'))
						.tooltip('fixTitle')
				}, 3000);
			});
			clipboard.on('error', function (e) {
				var $trigger = $(e.trigger);
				var $menu = $trigger.next('.share-menu').find('.popovermenu');
				var $linkTextMenu = $menu.find('li.linkTextMenu');
				var $input = $linkTextMenu.find('.linkText');

				var $li = $trigger.closest('li[data-share-id]');
				var shareId = $li.data('share-id');

				// show menu
				OC.showMenu(null, $menu);

				var actionMsg = '';
				if (/iPhone|iPad/i.test(navigator.userAgent)) {
					actionMsg = t('core', 'Not supported!');
				} else if (/Mac/i.test(navigator.userAgent)) {
					actionMsg = t('core', 'Press ⌘-C to copy.');
				} else {
					actionMsg = t('core', 'Press Ctrl-C to copy.');
				}

				$linkTextMenu.removeClass('hidden');
				$input.select();
				$input.tooltip('hide')
					.attr('data-original-title', actionMsg)
					.tooltip('fixTitle')
					.tooltip({placement: 'bottom', trigger: 'manual'})
					.tooltip('show');
				_.delay(function () {
					$input.tooltip('hide');
					$input.attr('data-original-title', t('core', 'Copy'))
						  .tooltip('fixTitle');
				}, 3000);
			});
		},

		newShare: function(event) {
			var self = this;
			var $target = $(event.target);
			var $li = $target.closest('li[data-share-id]');
			var shareId = $li.data('share-id');
			var $loading = $li.find('.share-menu > .icon-loading-small');

			if(!$loading.hasClass('hidden') && this.password === '') {
				// in process
				return false;
			}

			// hide all icons and show loading
			$li.find('.icon').addClass('hidden');
			$loading.removeClass('hidden');

			// hide menu
			OC.hideMenus();

			var shareData = {}

			var isPasswordEnforced = this.configModel.get('enforcePasswordForPublicLink');
			var isExpirationEnforced = this.configModel.get('isDefaultExpireDateEnforced');

			// set default expire date
			if (isExpirationEnforced) {
				var defaultExpireDays = this.configModel.get('defaultExpireDate');
				var expireDate = moment().add(defaultExpireDays, 'day').format('DD-MM-YYYY')
				shareData.expireDate = expireDate;
			}

			// if password is set, add to data
			if (isPasswordEnforced && this.password !== '') {
				shareData.password = this.password
			}

			var newShareId = false;

			// We need a password before the share creation
			if (isPasswordEnforced && !this.showPending && this.password === '') {
				this.showPending = shareId;
				var self = this.render();
				self.$el.find('.pending #enforcedPassText').focus();
			} else {
				// else, we have a password or it is not enforced
				$.when(this.model.saveLinkShare(shareData, {
					success: function() {
						$loading.addClass('hidden');
						$li.find('.icon').removeClass('hidden');
						self.render();
						// open the menu by default
						// we can only do that after the render
						if (newShareId) {
							var shares = self.$el.find('li[data-share-id]');
							var $newShare = self.$el.find('li[data-share-id="'+newShareId+'"]');
							// only open the menu by default if this is the first share
							if ($newShare && shares.length === 1) {
								$menu = $newShare.find('.popovermenu');
								OC.showMenu(null, $menu);
							}
						}
					},
					error: function() {
						// empty function to override the default Dialog warning
					}
				})).fail(function(response) {
					// password failure? Show error
					self.password = ''
					if (isPasswordEnforced && response && response.responseJSON && response.responseJSON.ocs.meta && response.responseJSON.ocs.meta.message) {
						$input = self.$el.find('.pending #enforcedPassText')
						$input.tooltip('destroy');
						$input.attr('title', response.responseJSON.ocs.meta.message);
						$input.tooltip({placement: 'bottom', trigger: 'manual'});
						$input.tooltip('show');
					} else {
						OC.Notification.showTemporary(t('core', 'Unable to create a link share'));
						$loading.addClass('hidden');
						$li.find('.icon').removeClass('hidden');
					}
				}).then(function(response) {
					// resolve before success
					newShareId = response.ocs.data.id
				});
			}
		},

		enforcedPasswordSet: function(event) {
			event.preventDefault();
			var $form = $(event.target);
			var $input = $form.find('input.enforcedPassText');
			this.password = $input.val();
			this.showPending = false;
			this.newShare(event);
		},

		onLinkTextClick: function(event) {
			var $element = $(event.target);
			var $li = $element.closest('li[data-share-id]');
			var $el = $li.find('.linkText');
			$el.focus();
			$el.select();
		},

		onHideDownloadChange: function(event) {
			var $element = $(event.target);
			var $li = $element.closest('li[data-share-id]');
			var shareId = $li.data('share-id');
			var $checkbox = $li.find('.hideDownloadCheckbox');
			$checkbox.siblings('.icon-loading-small').removeClass('hidden').addClass('inlineblock');

			var hideDownload = false;
			if($checkbox.is(':checked')) {
				hideDownload = true;
			}

			this.model.saveLinkShare({
				hideDownload: hideDownload,
				cid: shareId
			}, {
				success: function() {
					$checkbox.siblings('.icon-loading-small').addClass('hidden').removeClass('inlineblock');
				},
				error: function(obj, msg) {
					OC.Notification.showTemporary(t('core', 'Unable to toggle this option'));
					$checkbox.siblings('.icon-loading-small').addClass('hidden').removeClass('inlineblock');
				}
			});
		},

		onShowPasswordClick: function(event) {
			var $element = $(event.target);
			var $li = $element.closest('li[data-share-id]');
			var shareId = $li.data('share-id');
			$li.find('.linkPass').slideToggle(OC.menuSpeed);
			$li.find('.linkPassMenu').toggleClass('hidden');
			if(!$li.find('.showPasswordCheckbox').is(':checked')) {
				this.model.saveLinkShare({
					password: '',
					cid: shareId
				});
			} else {
				if (!OC.Util.isIE()) {
					$li.find('.linkPassText').focus();
				}
			}
		},

		onPasswordKeyUp: function(event) {
			if(event.keyCode === 13) {
				this.onPasswordEntered(event);
			}
		},

		onPasswordEntered: function(event) {
			var $element = $(event.target);
			var $li = $element.closest('li[data-share-id]');
			var shareId = $li.data('share-id');
			var $loading = $li.find('.linkPassMenu .icon-loading-small');
			if (!$loading.hasClass('hidden')) {
				// still in process
				return;
			}
			var $input = $li.find('.linkPassText');
			$input.removeClass('error');
			$input.parent().find('input').removeClass('error');
			var password = $input.val();

			if ($li.find('.linkPassText').attr('placeholder') === PASSWORD_PLACEHOLDER_MESSAGE_OPTIONAL) {

				// in IE9 the password might be the placeholder due to bugs in the placeholders polyfill
				if(password === PASSWORD_PLACEHOLDER_MESSAGE_OPTIONAL) {
					password = '';
				}
			} else {

				// in IE9 the password might be the placeholder due to bugs in the placeholders polyfill
				if(password === '' || password === PASSWORD_PLACEHOLDER || password === PASSWORD_PLACEHOLDER_MESSAGE) {
					return;
				}
			}

			$loading
				.removeClass('hidden')
				.addClass('inlineblock');

			this.model.saveLinkShare({
				password: password,
				cid: shareId
			}, {
				complete: function(model) {
					$loading.removeClass('inlineblock').addClass('hidden');
				},
				error: function(model, msg) {
					// Add visual feedback to both the input and the submit button
					$input.parent().find('input').addClass('error');

					// destroy old tooltips
					var $container = $input.parent();
					$container.tooltip('destroy');
					$input.addClass('error');
					$container.attr('title', msg);
					$container.tooltip({placement: 'bottom', trigger: 'manual'});
					$container.tooltip('show');
				}
			});
		},

		onPasswordByTalkChange: function(event) {
			var $element = $(event.target);
			var $li = $element.closest('li[data-share-id]');
			var shareId = $li.data('share-id');
			var $checkbox = $li.find('.passwordByTalkCheckbox');
			$checkbox.siblings('.icon-loading-small').removeClass('hidden').addClass('inlineblock');

			var sendPasswordByTalk = false;
			if($checkbox.is(':checked')) {
				sendPasswordByTalk = true;
			}

			this.model.saveLinkShare({
				sendPasswordByTalk: sendPasswordByTalk,
				cid: shareId
			}, {
				success: function() {
					$checkbox.siblings('.icon-loading-small').addClass('hidden').removeClass('inlineblock');
				},
				error: function(obj, msg) {
					OC.Notification.showTemporary(t('core', 'Unable to toggle this option'));
					$checkbox.siblings('.icon-loading-small').addClass('hidden').removeClass('inlineblock');
				}
			});
		},

		onAllowPublicEditingChange: function(event) {
			var $element = $(event.target);
			var $li = $element.closest('li[data-share-id]');
			var shareId = $li.data('share-id');
			var $checkbox = $li.find('.publicEditingCheckbox');
			$checkbox.siblings('.icon-loading-small').removeClass('hidden').addClass('inlineblock');

			var permissions = OC.PERMISSION_READ;
			if($checkbox.is(':checked')) {
				permissions = OC.PERMISSION_UPDATE | OC.PERMISSION_READ;
			}

			this.model.saveLinkShare({
				permissions: permissions,
				cid: shareId
			}, {
				success: function() {
					$checkbox.siblings('.icon-loading-small').addClass('hidden').removeClass('inlineblock');
				},
				error: function(obj, msg) {
					OC.Notification.showTemporary(t('core', 'Unable to toggle this option'));
					$checkbox.siblings('.icon-loading-small').addClass('hidden').removeClass('inlineblock');
				}
			});
		},


		onPublicUploadChange: function(event) {
			var $element = $(event.target);
			var $li = $element.closest('li[data-share-id]');
			var shareId = $li.data('share-id');
			var permissions = event.currentTarget.value;
			this.model.saveLinkShare({
				permissions: permissions,
				cid: shareId
			});
		},

		showNoteForm: function(event) {
			event.preventDefault();
			event.stopPropagation();
			var self = this;
			var $element = $(event.target);
			var $li = $element.closest('li[data-share-id]');
			var $menu = $element.closest('li');
			var $form = $menu.next('li.share-note-form');

			// show elements
			$menu.find('.share-note-delete').toggleClass('hidden');
			$form.toggleClass('hidden');
			$form.find('textarea').focus();
		},

		deleteNote: function(event) {
			event.preventDefault();
			event.stopPropagation();
			var self = this;
			var $element = $(event.target);
			var $li = $element.closest('li[data-share-id]');
			var shareId = $li.data('share-id');
			var $menu = $element.closest('li');
			var $form = $menu.next('li.share-note-form');

			$form.find('.share-note').val('');

			$form.addClass('hidden');
			$menu.find('.share-note-delete').addClass('hidden');

			self.sendNote('', shareId, $menu);
		},

		updateNote: function(event) {
			event.preventDefault();
			event.stopPropagation();
			var self = this;
			var $element = $(event.target);
			var $li = $element.closest('li[data-share-id]');
			var shareId = $li.data('share-id');
			var $form = $element.closest('li.share-note-form');
			var $menu = $form.prev('li');
			var message = $form.find('.share-note').val().trim();

			if (message.length < 1) {
				return;
			}

			self.sendNote(message, shareId, $menu);
		},

		sendNote: function(note, shareId, $menu) {
			var $form = $menu.next('li.share-note-form');
			var $submit = $form.find('input.share-note-submit');
			var $error = $form.find('input.share-note-error');

			$submit.prop('disabled', true);
			$menu.find('.icon-loading-small').removeClass('hidden');
			$menu.find('.icon-edit').hide();

			var complete = function() {
				$submit.prop('disabled', false);
				$menu.find('.icon-loading-small').addClass('hidden');
				$menu.find('.icon-edit').show();
			};
			var error = function() {
				$error.show();
				setTimeout(function() {
					$error.hide();
				}, 3000);
			};

			// send data
			$.ajax({
				method: 'PUT',
				url: OC.linkToOCS('apps/files_sharing/api/v1/shares',2) + shareId + '?' + OC.buildQueryString({format: 'json'}),
				data: { note: note },
				complete : complete,
				error: error
			});
		},

		render: function() {
			this.$el.find('.has-tooltip').tooltip();

			// reset previously set passwords
			this.password = '';

			var linkShareTemplate = this.template();
			var resharingAllowed = this.model.sharePermissionPossible();

			if(!resharingAllowed
				|| !this.showLink
				|| !this.configModel.isShareWithLinkAllowed())
			{
				var templateData = {shareAllowed: false};
				if (!resharingAllowed) {
					// add message
					templateData.noSharingPlaceholder = t('core', 'Resharing is not allowed');
				}
				this.$el.html(linkShareTemplate(templateData));
				return this;
			}

			var publicUpload =
				this.model.isFolder()
				&& this.model.createPermissionPossible()
				&& this.configModel.isPublicUploadEnabled();


			var publicEditingChecked = '';
			if(this.model.isPublicEditingAllowed()) {
				publicEditingChecked = 'checked="checked"';
			}

			var isPasswordEnforced = this.configModel.get('enforcePasswordForPublicLink');
			var isPasswordEnabledByDefault = this.configModel.get('enableLinkPasswordByDefault') === true;
			var passwordPlaceholderInitial = this.configModel.get('enforcePasswordForPublicLink')
				? PASSWORD_PLACEHOLDER_MESSAGE : PASSWORD_PLACEHOLDER_MESSAGE_OPTIONAL;

			var publicEditable =
				!this.model.isFolder()
				&& this.model.updatePermissionPossible();

			var isExpirationEnforced = this.configModel.get('isDefaultExpireDateEnforced');

			// what if there is another date picker on that page?
			var minDate = new Date();
			// min date should always be the next day
			minDate.setDate(minDate.getDate()+1);

			$.datepicker.setDefaults({
				minDate: minDate
			});

			this.$el.find('.datepicker').datepicker({dateFormat : 'dd-mm-yy'});

			var minPasswordLength = 4
			// password policy?
			if(oc_capabilities.password_policy && oc_capabilities.password_policy.minLength) {
				minPasswordLength = oc_capabilities.password_policy.minLength;
			}

			var popoverBase = {
				urlLabel: t('core', 'Link'),
				hideDownloadLabel: t('core', 'Hide download'),
				enablePasswordLabel: isPasswordEnforced ? t('core', 'Password protection enforced') : t('core', 'Password protect'),
				passwordLabel: t('core', 'Password'),
				passwordPlaceholderInitial: passwordPlaceholderInitial,
				publicUpload: publicUpload,
				publicEditing: publicEditable,
				publicEditingChecked: publicEditingChecked,
				publicEditingLabel: t('core', 'Allow editing'),
				mailPrivatePlaceholder: t('core', 'Email link to person'),
				mailButtonText: t('core', 'Send'),
				publicUploadRWLabel: t('core', 'Allow upload and editing'),
				publicUploadRLabel: t('core', 'Read only'),
				publicUploadWLabel: t('core', 'File drop (upload only)'),
				publicUploadRWValue: OC.PERMISSION_UPDATE | OC.PERMISSION_CREATE | OC.PERMISSION_READ | OC.PERMISSION_DELETE,
				publicUploadRValue: OC.PERMISSION_READ,
				publicUploadWValue: OC.PERMISSION_CREATE,
				expireDateLabel: isExpirationEnforced ? t('core', 'Expiration date enforced') : t('core', 'Set expiration date'),
				expirationLabel: t('core', 'Expiration'),
				expirationDatePlaceholder: t('core', 'Expiration date'),
				isExpirationEnforced: isExpirationEnforced,
				isPasswordEnforced: isPasswordEnforced,
				defaultExpireDate: moment().add(1, 'day').format('DD-MM-YYYY'), // Can't expire today
				addNoteLabel: t('core', 'Note to recipient'),
				unshareLabel: t('core', 'Unshare'),
				unshareLinkLabel: t('core', 'Delete share link'),
				newShareLabel: t('core', 'Add another link'),
			};

			var pendingPopover = {
				isPasswordEnforced: isPasswordEnforced,
				enforcedPasswordLabel: t('core', 'Password protection for links is mandatory'),
				passwordPlaceholder: passwordPlaceholderInitial,
				minPasswordLength: minPasswordLength,
			};
			var pendingPopoverMenu = this.pendingPopoverMenuTemplate(_.extend({}, pendingPopover))

			var linkShares = this.getShareeList();
			if(_.isArray(linkShares)) {
				for (var i = 0; i < linkShares.length; i++) {
					var social = [];
					OC.Share.Social.Collection.each(function (model) {
						var url = model.get('url');
						url = url.replace('{{reference}}', linkShares[i].shareLinkURL);
						social.push({
							url: url,
							label: t('core', 'Share to {name}', {name: model.get('name')}),
							name: model.get('name'),
							iconClass: model.get('iconClass'),
							newWindow: model.get('newWindow')
						});
					});
					var popover = this.getPopoverObject(linkShares[i])
					linkShares[i].popoverMenu = this.popoverMenuTemplate(_.extend({}, popoverBase, popover, {social: social}));
					linkShares[i].pendingPopoverMenu = pendingPopoverMenu
				}
			}

			this.$el.html(linkShareTemplate({
				linkShares: linkShares,
				shareAllowed: true,
				nolinkShares: linkShares.length === 0,
				newShareLabel: t('core', 'Share link'),
				newShareTitle: t('core', 'New share link'),
				pendingPopoverMenu: pendingPopoverMenu,
				showPending: this.showPending === this.newShareId,
				newShareId: this.newShareId,
			}));

			this.delegateEvents();

			// new note autosize
			autosize(this.$el.find('.share-note-form .share-note'));

			return this;
		},

		onToggleMenu: function(event) {
			event.preventDefault();
			event.stopPropagation();
			var $element = $(event.target);
			var $li = $element.closest('li[data-share-id]');
			var $menu = $li.find('.sharingOptionsGroup .popovermenu');
			var shareId = $li.data('share-id');

			OC.showMenu(null, $menu);

			// focus the password if not set and enforced
			var isPasswordEnabledByDefault = this.configModel.get('enableLinkPasswordByDefault') === true;
			var haspassword = $menu.find('.linkPassText').val() !== '';

			if (!haspassword && isPasswordEnabledByDefault) {
				$menu.find('.linkPassText').focus();
			}
		},

		/**
		 * @returns {Function} from Handlebars
		 * @private
		 */
		template: function () {
			return OC.Share.Templates['sharedialoglinkshareview'];
		},

		/**
		 * renders the popover template and returns the resulting HTML
		 *
		 * @param {Object} data
		 * @returns {string}
		 */
		popoverMenuTemplate: function(data) {
			return OC.Share.Templates['sharedialoglinkshareview_popover_menu'](data);
		},

		/**
		 * renders the pending popover template and returns the resulting HTML
		 *
		 * @param {Object} data
		 * @returns {string}
		 */
		pendingPopoverMenuTemplate: function(data) {
			return OC.Share.Templates['sharedialoglinkshareview_popover_menu_pending'](data);
		},

		onPopUpClick: function(event) {
			event.preventDefault();
			event.stopPropagation();

			var url = $(event.currentTarget).data('url');
			var newWindow = $(event.currentTarget).data('window');
			$(event.currentTarget).tooltip('hide');
			if (url) {
				if (newWindow === true) {
					var width = 600;
					var height = 400;
					var left = (screen.width / 2) - (width / 2);
					var top = (screen.height / 2) - (height / 2);

					window.open(url, 'name', 'width=' + width + ', height=' + height + ', top=' + top + ', left=' + left);
				} else {
					window.location.href = url;
				}
			}
		},

		onExpireDateChange: function(event) {
			var $element = $(event.target);
			var li = $element.closest('li[data-share-id]');
			var shareId = li.data('share-id');
			var expirationDatePicker = '#expirationDateContainer-' + shareId;
			var datePicker = $(expirationDatePicker);
			var state = $element.prop('checked');
			datePicker.toggleClass('hidden', !state);

			if (!state) {
				// disabled, let's hide the input and
				// set the expireDate to nothing
				$element.closest('li').next('li').addClass('hidden');
				this.setExpirationDate('', shareId);
			} else {
				// enabled, show the input and the datepicker
				$element.closest('li').next('li').removeClass('hidden');
				this.showDatePicker(event);

			}
		},

		showDatePicker: function(event) {
			var $element = $(event.target);
			var li = $element.closest('li[data-share-id]');
			var shareId = li.data('share-id');
			var maxDate = $element.data('max-date');
			var expirationDatePicker = '#expirationDatePicker-' + shareId;
			var self = this;

			$(expirationDatePicker).datepicker({
				dateFormat : 'dd-mm-yy',
				onSelect: function (expireDate) {
					self.setExpirationDate(expireDate, shareId);
				},
				maxDate: maxDate
			});
			$(expirationDatePicker).datepicker('show');
			$(expirationDatePicker).focus();

		},

		setExpirationDate: function(expireDate, shareId) {
			this.model.saveLinkShare({expireDate: expireDate, cid: shareId});
		},

		onChangeExpirationDate: function(event) {
			var $element = $(event.target);
			var expireDate = $element.val();
			var li = $element.closest('li[data-share-id]');
			var shareId = li.data('share-id');
			var expirationDatePicker = '#expirationDatePicker-' + shareId;

			this.setExpirationDate(expireDate, shareId);
			$(expirationDatePicker).datepicker('hide');
		},

		/**
		 * get an array of sharees' share properties
		 *
		 * @returns {Array}
		 */
		getShareeList: function() {
			var shares = this.model.get('linkShares');

			if(!this.model.hasLinkShares()) {
				return [];
			}

			var list = [];
			for(var index = 0; index < shares.length; index++) {
				var share = this.getShareeObject(index);
				// first empty {} is necessary, otherwise we get in trouble
				// with references
				list.push(_.extend({}, share));
			}

			return list;
		},

		/**
		 *
		 * @param {OC.Share.Types.ShareInfo} shareInfo
		 * @returns {object}
		 */
		getShareeObject: function(shareIndex) {
			var share = this.model.get('linkShares')[shareIndex];

			return _.extend({}, share, {
				cid: share.id,
				shareAllowed: true,
				linkShareLabel: share.label ? share.label : t('core', 'Share link'),
				popoverMenu: {},
				shareLinkURL: share.url,
				newShareTitle: t('core', 'New share link'),
				copyLabel: t('core', 'Copy link'),
				showPending: this.showPending === share.id,
				linkShareCreationDate: t('core', 'Created on {time}', { time: moment(share.stime * 1000).format('LLLL') })
			})
		},

		getPopoverObject: function(share) {
			var publicUploadRWChecked = '';
			var publicUploadRChecked = '';
			var publicUploadWChecked = '';

			switch (this.model.linkSharePermissions(share.id)) {
				case OC.PERMISSION_READ:
					publicUploadRChecked = 'checked';
					break;
				case OC.PERMISSION_CREATE:
					publicUploadWChecked = 'checked';
					break;
				case OC.PERMISSION_UPDATE | OC.PERMISSION_CREATE | OC.PERMISSION_READ | OC.PERMISSION_DELETE:
					publicUploadRWChecked = 'checked';
					break;
			}

			var isPasswordSet = !!share.password;
			var isPasswordEnabledByDefault = this.configModel.get('enableLinkPasswordByDefault') === true;
			var isPasswordEnforced = this.configModel.get('enforcePasswordForPublicLink');
			var isExpirationEnforced = this.configModel.get('isDefaultExpireDateEnforced');
			var defaultExpireDays = this.configModel.get('defaultExpireDate');
			var hasExpireDate = !!share.expiration || isExpirationEnforced;

			var expireDate;
			if (hasExpireDate) {
				expireDate = moment(share.expiration, 'YYYY-MM-DD').format('DD-MM-YYYY');
			}

			var isTalkEnabled = oc_appswebroots['spreed'] !== undefined;
			var sendPasswordByTalk = share.sendPasswordByTalk;

			var hideDownload = share.hideDownload;

			var maxDate = null;

			if(hasExpireDate) {
				if(isExpirationEnforced) {
					// TODO: hack: backend returns string instead of integer
					var shareTime = share.stime;
					if (_.isNumber(shareTime)) {
						shareTime = new Date(shareTime * 1000);
					}
					if (!shareTime) {
						shareTime = new Date(); // now
					}
					shareTime = OC.Util.stripTime(shareTime).getTime();
					maxDate = new Date(shareTime + defaultExpireDays * 24 * 3600 * 1000);
				}
			}

			return {
				cid: share.id,
				shareLinkURL: share.url,
				passwordPlaceholder: isPasswordSet ? PASSWORD_PLACEHOLDER : PASSWORD_PLACEHOLDER_MESSAGE,
				isPasswordSet: isPasswordSet || isPasswordEnabledByDefault || isPasswordEnforced,
				showPasswordByTalkCheckBox: isTalkEnabled && isPasswordSet,
				passwordByTalkLabel: t('core', 'Password protect by Talk'),
				isPasswordByTalkSet: sendPasswordByTalk,
				publicUploadRWChecked: publicUploadRWChecked,
				publicUploadRChecked: publicUploadRChecked,
				publicUploadWChecked: publicUploadWChecked,
				hasExpireDate: hasExpireDate,
				expireDate: expireDate,
				shareNote: share.note,
				hasNote: share.note !== '',
				maxDate: maxDate,
				hideDownload: hideDownload,
				isExpirationEnforced: isExpirationEnforced,
			}
		},

		onUnshare: function(event) {
			event.preventDefault();
			event.stopPropagation();
			var self = this;
			var $element = $(event.target);
			if (!$element.is('a')) {
				$element = $element.closest('a');
			}

			var $loading = $element.find('.icon-loading-small').eq(0);
			if(!$loading.hasClass('hidden')) {
				// in process
				return false;
			}
			$loading.removeClass('hidden');

			var $li = $element.closest('li[data-share-id]');

			var shareId = $li.data('share-id');

			self.model.removeShare(shareId, {
				success: function() {
					$li.remove();
					self.render()
				},
				error: function() {
					$loading.addClass('hidden');
					OC.Notification.showTemporary(t('core', 'Could not unshare'));
				}
			});
			return false;
		},


	});

	OC.Share.ShareDialogLinkShareView = ShareDialogLinkShareView;

})();
