class ez5.PdfCreator.Node.Field extends ez5.PdfCreator.Node

	@getName: ->
		"field"

	__renderPdfContent: (_opts) ->
		data = @getData()
		mask = @__getMask()

		if CUI.util.isEmpty(_opts.object)
			return

		selectedFields = ez5.PdfCreator.Node.Field.getSelectedFields(data)
		if CUI.util.isEmpty(selectedFields)
			span = CUI.dom.span()
			span.textContent = $$("pdf-creator.settings.node.field.empty-fields")
			return span

		getFieldData = (field, opts = {}) ->
			fieldName = ez5.PdfCreator.Node.Field.getFieldName(field, opts)
			if not fieldName
				return
			return selectedFields[fieldName]

		fieldsRendererPlain = new FieldsRendererPlain()

		mask.invokeOnFields("all", true, (field) =>
			if not getFieldData(field)
				return
			fieldsRendererPlain.addField(field)
		)

		objecttypeName = @__getObjecttypeName()
		opts =
			mode: _opts.mode or "detail" # Perhaps change to "all"? in that case we need to introduce the isVisible in Mask.
			data: _opts.object[objecttypeName]
			top_level_data: _opts.object
			inline_mode: data.linked_object_mode
			nested_condensed_output: data.nested_condensed_output
			for_print: true
			removeBlockWidth: true #Rempve the block-width custom setting from the field.
			nested_only_first_row: data.nested_only_first_row
			nested_display_as_table: data.nested_display_as_table
			getLabel: (field, _, opts) =>
				fieldData = getFieldData(field, opts)
				displayName = ez5.loca.getBestFrontendValue(fieldData?.label)
				label = new CUI.Label
					class: "ez5-field-label"
					text: displayName
					multiline: true
				return label
			isVisible: (field, _, opts) =>
				return not CUI.util.isEmpty(getFieldData(field, opts))
		element = fieldsRendererPlain.render(opts)

		if data.row_format
			CUI.dom.addClass(element, "row-format")
		if data.hide_labels
			CUI.dom.addClass(element, "hide-labels")

		return element

	__getSettingsFields: ->
		@__fieldSelectorButton = new CUI.FormButton
			form: label: $$("pdf-creator.settings.node.field.fields|label")
			text: $$("pdf-creator.settings.node.field.select-fields.button")
			disabled: not @__getMask()
			onClick: =>
				@__showFieldSelector()

		@__fieldsSelectedLabel = new CUI.Label(text: "")

		onHideLabelsChanged = (data, field) ->
			rowFormatField = field.getForm().getFieldsByName("row_format")[0]
			# When labels are hidden, it makes no sense to enable the 'row format' checkbox.
			if data.hide_labels
				rowFormatField.disable()
			else
				rowFormatField.enable()
			return

		fields = [
			@__fieldSelectorButton
		,
			new CUI.DataFieldProxy
				element: =>
					@__showSelectedFields()
					@__fieldsSelectedLabel
		,
			type: CUI.Select
			name: "linked_object_mode"
			form:
				label: $$("pdf-creator.settings.node.field.linked-object-mode|label")
				hint: $$("pdf-creator.settings.node.field.linked-object-mode|hint")
			options: =>
				return ["text", "short", "standard"].map((value) =>
					text: $$("pdf-creator.settings.node.field.linked-object-mode.option.#{value}")
					value: value
				)
		,
			type: CUI.Checkbox
			form: label: $$("pdf-creator.settings.node.field.nested-condensed-output|label")
			name: "nested_condensed_output"
		,
			type: CUI.Checkbox
			form: label: $$("pdf-creator.settings.node.field.nested_display_as_table|label")
			name: "nested_display_as_table"
		,
			type: CUI.Checkbox
			form: label: $$("pdf-creator.settings.node.field.hide_labels|label")
			name: "hide_labels"
			onDataChanged: onHideLabelsChanged
		,
			type: CUI.Checkbox
			form: label: $$("pdf-creator.settings.node.field.row_format|label")
			name: "row_format"
			onDataInit: (field, data) -> onHideLabelsChanged(data, field)
		,
			type: CUI.Checkbox
			form: label: $$("pdf-creator.settings.node.field.nested_only_first_row|label")
			name: "nested_only_first_row"
		]

		return fields

	__getStyleSettings: ->
		return ["class-name"]

	__showSelectedFields: () ->
		data = @getData()
		selectedFields = ez5.PdfCreator.Node.Field.getSelectedFields(data)
		selectedFieldsCount = Object.keys(selectedFields).length
		if selectedFieldsCount == 0
			@__fieldsSelectedLabel.setText($$("pdf-creator.settings.node.field.select-fields.no-fields-selected|label"))
		else
			@__fieldsSelectedLabel.setText($$("pdf-creator.settings.node.field.select-fields.count|label", count: selectedFieldsCount))
		return

	__showFieldSelector: () ->
		mask = @__getMask()
		@__currentMask = mask
		data = @getData()
		data.dataFields = data.dataFields or {}

		objecttypeManager = new ObjecttypeManager()
		objecttypeManager.addMask(@__getMask())
		objecttypeManager.initCommonFields("all")

		panelStates = {}
		currentFieldsForm = null

		# FieldSelectionTemplates is provided by the frontend. Guard against older
		# frontends that don't ship it yet, so the plugin keeps working without it.
		fieldTemplates = null
		if ez5.version("6") and typeof FieldSelectionTemplates isnt "undefined"
			fieldTemplates = new FieldSelectionTemplates
				getObjecttypes: => [mask.getTable().name()]
				getState: =>
					fields = {}
					for fieldName, fieldValue of data.dataFields
						fields[fieldName] = !!fieldValue._enabled
					panels = if currentFieldsForm then currentFieldsForm.getPanelStates() else {}
					fields: fields, panels: panels
				applyState: (template) =>
					savedFields = template.fields or {}
					for fieldName, fieldValue of data.dataFields
						if fieldValue._disabled
							continue
						if Object.prototype.hasOwnProperty.call(savedFields, fieldName)
							fieldValue._enabled = !!savedFields[fieldName]
					panelStates = template.panels or {}
					renderModal()
				reload: =>
					if currentFieldsForm
						panelStates = currentFieldsForm.getPanelStates()
					renderModal()

		renderModal = =>
			fieldsForm = new FieldsForm
				otm: objecttypeManager
				data: data.dataFields
				# Only set on frontends that support it (same feature as the templates menu).
				panelStates: (panelStates if fieldTemplates)
				treeNodeClass: PdfFieldsFormNode
				acceptField: (field, fieldsFormNodeFather) ->
					if not field.mask
						return false

					#We need to check if the custom data field is visible for print
					if field instanceof CustomDataType and not field.isVisible("detail", for_print: true)
						return false

					if field instanceof CustomDataTypeMappingField
						return false

					# Linked object inside linked object not allowed.
#					if field instanceof LinkedObject and fieldsFormNodeFather?.field instanceof LinkedObject
#						return false

					return true
				treeOpts:
					class: 'cui-lv--has-datafields'
					maximize: false
					rowMove: false
					cols: ["auto"]
					fixedRows: 0
			currentFieldsForm = fieldsForm

			fieldsFormDiv = fieldsForm.renderForm()
			fieldsForm.open()

			# Checkbox to hide/show system fields to make the field selection easier.
			hideSystemFieldsCheckbox = new CUI.Checkbox
				text: $$("pdf-creator.settings.node.field.select-fields.modal.checkbox.hide-system-fields")
				onClick: () ->
					hideShowColumns = (nodes) ->
						for node in nodes
							if hideSystemFieldsCheckbox.isActive() and node.field.isTopLevelField()
								node.hide()
							else
								node.show()

							if node.children
								hideShowColumns(node.children)

						return
					hideShowColumns(fieldsForm.getNodes())
					return

			hideSystemFieldsCheckbox.start()

			pane =
				header_left: new CUI.Label
					text: $$("pdf-creator.settings.node.field.select-fields.modal.header")
				content: fieldsFormDiv
				footer_left: hideSystemFieldsCheckbox
				footer_right: new CUI.Button
					text: $$("pdf-creator.settings.node.field.select-fields.modal.button")
					primary: true
					onClick: =>
						@__showSelectedFields()

						CUI.Events.trigger
							node: @__fieldSelectorButton
							type: "data-changed"
							info:
								element: @__fieldSelectorButton

						@__fieldSelectorModal.hide()
						return
			if fieldTemplates
				pane.header_right = fieldTemplates.getMenuButton()

			@__fieldSelectorModal?.destroy()
			@__fieldSelectorModal = new CUI.Modal
				class: "pdf-creator-field-selector"
				pane: pane
			@__fieldSelectorModal.show()
			return

		renderModal()
		return

	getData: (isForSaving = false) ->
		data = super()
		if not isForSaving
			return data
		if data.dataFields
			# To avoid saving unnecessary data, remove the fields that are not enabled.
			for key, value of data.dataFields
				if value._enabled
					continue
				delete data.dataFields[key]
		return data

	@getFieldName: (field, opts = {}) ->
		# If it has not a mask we skip it (Mask splitters for example)
		if not field.mask
			return

		if opts._path
			# This means that the field is inside a linked object.
			fieldName = opts._path + "." + field.fullName(false)
		else
			fieldName = field.fullName()
		return fieldName

	# Returns an object with the enabled fields for this node.
	# It is used by itself and by the pdf creator getTemplateFields method.
	@getSelectedFields: (data) ->
		if not data.dataFields
			return {}

		fields = {}
		for key, value of data.dataFields
			if not value._enabled
				continue
			fields[key] = value
		return fields


ez5.PdfCreator.plugins.registerPlugin(ez5.PdfCreator.Node.Field)
