pragma ComponentBehavior: Bound

import QtQuick
import qs.Effects

CustomListView {
	id: root

	property real endFadeOpacity: fadeShouldBeActive(false) ? 0 : 1
	property real fadeAmount: 0.1
	property real fadeThreshold: 0.0
	readonly property bool horizontal: orientation === ListView.Horizontal
	property real startFadeOpacity: fadeShouldBeActive(true) ? 0 : 1

	function contentSize(): real {
		return horizontal ? contentWidth : contentHeight;
	}

	function fadeShouldBeActive(isStart: bool): bool {
		// When content is smaller than flickable size, hide fade when rebound starts.
		if (contentSize() + marginStart() + marginEnd() < viewportSize() && rebound.running && ((isStart ? overshootStart() > 0 : overshootStart() < 0))) {
			return false;
		}

		if (isStart)
			return visibleStart() > 0;

		return visibleStart() + visibleRatio() < 1;
	}

	function marginEnd(): real {
		return horizontal ? rightMargin - fadeThreshold : bottomMargin - fadeThreshold;
	}

	function marginStart(): real {
		return horizontal ? leftMargin - fadeThreshold : topMargin - fadeThreshold;
	}

	function overshootStart(): real {
		return horizontal ? horizontalOvershoot : verticalOvershoot;
	}

	function viewportSize(): real {
		return horizontal ? width : height;
	}

	function visibleRatio(): real {
		return horizontal ? visibleArea.widthRatio : visibleArea.heightRatio;
	}

	function visibleStart(): real {
		return horizontal ? visibleArea.xPosition : visibleArea.yPosition;
	}

	flickableDirection: horizontal ? Flickable.HorizontalFlick : Flickable.VerticalFlick
	layer.enabled: true

	Behavior on endFadeOpacity {
		Anim {
			type: Anim.SlowEffects
		}
	}
	layer.effect: Mask {
		maskSource: mask

		Rectangle {
			id: mask

			anchors.fill: parent
			layer.enabled: true
			visible: false

			gradient: Gradient {
				orientation: root.horizontal ? Gradient.Horizontal : Gradient.Vertical

				GradientStop {
					color: Qt.rgba(0, 0, 0, root.startFadeOpacity)
					position: 0
				}

				GradientStop {
					color: Qt.rgba(0, 0, 0, 1)
					position: root.fadeAmount
				}

				GradientStop {
					color: Qt.rgba(0, 0, 0, 1)
					position: 1 - root.fadeAmount
				}

				GradientStop {
					color: Qt.rgba(0, 0, 0, root.endFadeOpacity)
					position: 1
				}
			}
		}
	}
	Behavior on startFadeOpacity {
		Anim {
			type: Anim.SlowEffects
		}
	}
}
