class FileList extends Class
	constructor: (@site, @inner_path, @is_owner=false) ->
		@need_update = true
		@error = null
		@url_root = "/list/" + @site + "/"
		if @inner_path
			@inner_path += "/"
			@url_root += @inner_path
		@log("inited", @url_root)
		@item_list = new FileItemList(@inner_path)
		@item_list.items = @item_list.items
		@menu_create = new Menu()

		@select_action = null
		@selected = {}
		@selected_items_num = 0
		@selected_items_size = 0
		@selected_optional_empty_num = 0

	isSelectedAll: ->
		false

	update: =>
		@item_list.update =>
			document.body.classList.add("loaded")

	getHref: (inner_path) =>
		return "/" + @site + "/" + inner_path

	getListHref: (inner_path) =>
		return "/list/" + @site + "/" + inner_path

	getEditHref: (inner_path, mode=null) =>
		href = @url_root + "?file=" + inner_path
		if mode
			href += "&edit_mode=#{mode}"
		return href

	checkSelectedItems: =>
		@selected_items_num = 0
		@selected_items_size = 0
		@selected_optional_empty_num = 0
		for item in @item_list.items
			if @selected[item.inner_path]
				@selected_items_num += 1
				@selected_items_size += item.size
				optional_info = @item_list.getOptionalInfo(item.inner_path)
				if optional_info and not optional_info.downloaded_percent > 0
					@selected_optional_empty_num += 1

	handleMenuCreateClick: =>
		@menu_create.items = []
		@menu_create.items.push ["File", @handleNewFileClick]
		@menu_create.items.push ["Directory", @handleNewDirectoryClick]
		@menu_create.toggle()
		return false

	handleNewFileClick: =>
		Page.cmd "wrapperPrompt", "New file name:", (file_name) =>
			window.top.location.href = @getEditHref(@inner_path + file_name, "new")
		return false

	handleNewDirectoryClick: =>
		Page.cmd "wrapperPrompt", "New directory name:", (res) =>
			alert("directory name #{res}")
		return false

	handleSelectClick: (e) =>
		return false

	handleSelectEnd: (e) =>
		document.body.removeEventListener('mouseup', @handleSelectEnd)
		@select_action = null

	handleSelectMousedown: (e) =>
		inner_path = e.currentTarget.attributes.inner_path.value
		if @selected[inner_path]
			delete @selected[inner_path]
			@select_action = "deselect"
		else
			@selected[inner_path] = true
			@select_action = "select"
		@checkSelectedItems()
		document.body.addEventListener('mouseup', @handleSelectEnd)
		e.stopPropagation()
		Page.projector.scheduleRender()
		return false

	handleRowMouseenter: (e) =>
		if e.buttons and @select_action
			inner_path = e.target.attributes.inner_path.value
			if @select_action == "select"
				@selected[inner_path] = true
			else
				delete @selected[inner_path]
			@checkSelectedItems()
			Page.projector.scheduleRender()
		return false

	handleSelectbarCancel: =>
		@selected = {}
		@checkSelectedItems()
		Page.projector.scheduleRender()
		return false

	handleSelectbarDelete: (e, remove_optional=false) =>
		for inner_path of @selected
			optional_info = @item_list.getOptionalInfo(inner_path)
			delete @selected[inner_path]
			if optional_info and not remove_optional
				Page.cmd "optionalFileDelete", inner_path
			else
				Page.cmd "fileDelete", inner_path
		@need_update = true
		Page.projector.scheduleRender()
		@checkSelectedItems()
		return false

	handleSelectbarRemoveOptional: (e) =>
		return @handleSelectbarDelete(e, true)

	renderSelectbar: =>
		h("div.selectbar", {classes: {visible: @selected_items_num > 0}}, [
			"Selected:",
			h("span.info", [
				h("span.num", "#{@selected_items_num} files"),
				h("span.size", "(#{Text.formatSize(@selected_items_size)})"),
			])
			h("div.actions", [
				if @selected_optional_empty_num > 0
					h("a.action.delete.remove_optional", {href: "#", onclick: @handleSelectbarRemoveOptional}, "Delete and remove optional")
				else
					h("a.action.delete", {href: "#", onclick: @handleSelectbarDelete}, "Delete")
			])
			h("a.cancel.link", {href: "#", onclick: @handleSelectbarCancel}, "Cancel")
		])

	renderHead: =>
		parent_links = []
		inner_path_parent = ""
		for parent_dir in @inner_path.split("/")
			if not parent_dir
				continue
			if inner_path_parent
				inner_path_parent += "/"
			inner_path_parent += "#{parent_dir}"
			parent_links.push(
				[" / ", h("a", {href: @getListHref(inner_path_parent)}, parent_dir)]
			)
		return h("div.tr.thead", h("div.td.full",
			h("a", {href: @getListHref("")}, "root"),
			parent_links
		))

	renderItemCheckbox: (item) =>
		if not @item_list.hasPermissionDelete(item)
			return [" "]

		return h("a.checkbox-outer", {
			href: "#Select",
			onmousedown: @handleSelectMousedown,
			onclick: @handleSelectClick,
			inner_path: item.inner_path
		}, h("span.checkbox"))

	renderItem: (item) =>
		if item.type == "parent"
			href = @url_root.replace(/^(.*)\/.{2,255}?$/, "$1/")
		else if item.type == "dir"
			href = @url_root + item.name
		else
			href = @url_root.replace(/^\/list\//, "/") + item.name

		inner_path = @inner_path + item.name
		href_edit = @getEditHref(inner_path)
		is_dir = item.type in ["dir", "parent"]
		ext = item.name.split(".").pop()

		is_editing = inner_path == Page.file_editor?.inner_path
		is_editable = not is_dir and item.size < 1024 * 1024 and ext not in window.BINARY_EXTENSIONS
		is_modified = @item_list.isModified(inner_path)
		is_added = @item_list.isAdded(inner_path)
		optional_info = @item_list.getOptionalInfo(inner_path)

		style = ""
		title = ""

		if optional_info
			downloaded_percent = optional_info.downloaded_percent
			if not downloaded_percent
				downloaded_percent = 0
			style += "background: linear-gradient(90deg, #fff6dd, #{downloaded_percent}%, white, #{downloaded_percent}%, white);"
			is_added = false

		if item.ignored
			is_added = false

		if is_modified then title += " (modified)"
		if is_added then title += " (new)"
		if optional_info or item.optional_empty then title += " (optional)"
		if item.ignored then title += " (ignored from content.json)"

		classes = {
			"type-#{item.type}": true, editing: is_editing, nobuttons: not is_editable, selected: @selected[inner_path],
			modified: is_modified, added: is_added, ignored: item.ignored, optional: optional_info, optional_empty: item.optional_empty
		}

		h("div.tr", {key: item.name, classes: classes, style: style, onmouseenter: @handleRowMouseenter, inner_path: inner_path}, [
			h("div.td.pre", {title: title},
				@renderItemCheckbox(item)
			),
			h("div.td.name", h("a.link", {href: href}, item.name))
			h("div.td.buttons", if is_editable then h("a.edit", {href: href_edit}, if Page.site_info.settings.own then "Edit" else "View"))
			h("div.td.size", if is_dir then "[DIR]" else Text.formatSize(item.size))
		])


	renderItems: =>
		return [
			if @item_list.error and not @item_list.items.length and not @item_list.updating then [
					h("div.tr", {key: "error"}, h("div.td.full.error", @item_list.error))
				],
			if @inner_path then @renderItem({"name": "..", type: "parent", size: 0})
			@item_list.items.map @renderItem
		]

	renderFoot: =>
		files = (item for item in @item_list.items when item.type not in ["parent", "dir"])
		dirs = (item for item in @item_list.items when item.type == "dir")
		if files.length
			total_size = (item.size for file in files).reduce (a, b) -> a + b
		else
			total_size = 0

		foot_text = "Total: "
		foot_text += "#{dirs.length} dir, #{files.length} file in #{Text.formatSize(total_size)}"

		return [
			if dirs.length or files.length or Page.site_info?.settings?.own
				h("div.tr.foot-info.foot", h("div.td.full", [
					if @item_list.updating
						"Updating file list..."
					else
						if dirs.length or files.length then foot_text
					if Page.site_info?.settings?.own
						h("div.create", [
							h("a.link", {href: "#Create+new+file", onclick: @handleNewFileClick}, "+ New")
							@menu_create.render()
						])
				]))
		]

	render: =>
		if @need_update
			@update()
			@need_update = false

			if not @item_list.items
				return []

		return h("div.files", [
			@renderSelectbar(),
			@renderHead(),
			h("div.tbody", @renderItems()),
			@renderFoot()
		])

window.FileList = FileList