<template>
	<div class="scroll">
		<Expand
			v-if="expanded"
			:expanded="expanded"
			class="expand-dark"
			@expand="(state) => $emit('expand', state)"
		/>

		<div class="scrollable">
			<Expand
				v-if="expanded"
				:expanded="expanded"
				class="expand-light"
				@expand="(state) => $emit('expand', state)"
			/>

			<div
				v-show="enabled && !expanded"
				class="scroll-button scroll-left noselect"
				:class="{ 'scroll-start': scrollAtStart }"
				@click="scroll('left')"
			><Icon icon="arrow-left3" /></div>

			<slot />

			<div
				v-show="enabled && !expanded"
				class="scroll-button scroll-right noselect"
				:class="{ 'scroll-end': scrollAtEnd }"
				@click="scroll('right')"
			><Icon icon="arrow-right3" /></div>
		</div>

		<Expand
			v-if="expanded || (expandable && scrollable)"
			:expanded="expanded"
			class="expand-dark"
			@expand="(state) => $emit('expand', state)"
		/>

		<Expand
			v-if="expanded || (expandable && scrollable)"
			:expanded="expanded"
			class="expand-light"
			@expand="(state) => $emit('expand', state)"
		/>
	</div>
</template>

<script>
import Expand from '../expand/expand.vue';

function updateScroll() {
	this.scrollable = this.target.scrollWidth > this.target.clientWidth;
	this.scrollAtStart = this.target.scrollLeft === 0;
	this.scrollAtEnd = this.target.scrollWidth - this.target.clientWidth === this.target.scrollLeft;
}

function scroll(direction) {
	if (direction === 'right') {
		this.target.scrollLeft = this.target.scrollLeft + this.target.clientWidth - 100;
	}

	if (direction === 'left') {
		this.target.scrollLeft = this.target.scrollLeft - this.target.clientWidth + 100;
	}
}

function mounted() {
	this.target = this.$slots.default[0].elm;

	this.target.addEventListener('scroll', () => this.updateScroll());
	window.addEventListener('resize', this.updateScroll);

	// typically triggered by slotted component when an image loads, affecting scrollWidth
	this.$on('load', () => this.updateScroll());
	this.updateScroll();
}

function beforeDestroy() {
	this.target.removeEventListener('scroll', this.updateScroll);

	window.removeEventListener('resize', this.updateScroll);
}

function updated() {
	this.updateScroll();
}

export default {
	components: {
		Expand,
	},
	props: {
		enabled: {
			type: Boolean,
			default: true,
		},
		expandable: {
			type: Boolean,
			default: true,
		},
		expanded: {
			type: Boolean,
			default: false,
		},
	},
	data() {
		return {
			target: null,
			scrollable: true,
			scrollAtStart: true,
			scrollAtEnd: false,
		};
	},
	mounted,
	updated,
	beforeDestroy,
	methods: {
		scroll,
		updateScroll,
	},
};
</script>

<style lang="scss" scoped>
@import 'theme';

.scroll {
	background: var(--profile);

	&.expanded {
		padding: 0;

		.scroll {
			display: none;
		}
	}
}

.scrollable {
	position: relative;
}

.expand-light {
	display: none;
}

.scroll-light {
	background: var(--background-dim);

	.scroll-button {
		.icon {
			fill: var(--darken);
		}

		&.scroll-start .icon,
		&.scroll-end .icon {
			fill: var(--darken-weak);
		}

		&:hover:not(.scroll-start):not(.scroll-end) .icon {
			fill: var(--text-dark);
		}
	}

	.scroll-left {
		background: linear-gradient(to right, var(--background-dim) 50%, transparent);
	}

	.scroll-right {
		background: linear-gradient(to left, var(--background-dim) 50%, transparent);
	}

	.expand-dark {
		display: none;
	}

	.expand-light {
		display: block;
	}
}

.scroll-dark {
	background: var(--profile);

	.scroll-button {
		.icon {
			fill: var(--lighten);
		}

		&.scroll-start .icon,
		&.scroll-end .icon {
			fill: var(--darken-weak);
		}

		&:hover:not(.scroll-start):not(.scroll-end) .icon {
			fill: var(--text-light);
		}
	}

	.scroll-left {
		background: linear-gradient(to right, var(--profile) 50%, transparent);
	}

	.scroll-right {
		background: linear-gradient(to left, var(--profile) 50%, transparent);
	}

	.expand-light {
		display: none;
	}

	.expand-dark {
		display: block;
	}
}

.scroll-button {
	height: 100%;
	display: flex;
	align-items: center;
	box-sizing: border-box;
	position: absolute;
	top: 0;
	bottom: 0;
	z-index: 10;

	&.scroll-start,
	&.scroll-end {
		/* use over v-show so button stays visible while still hovered */
		display: none;
	}

	&:hover {
		display: flex;
		cursor: pointer;
	}
}

.scroll-left {
	left: 0;
	padding: 1rem 2rem 1rem .5rem;
}

.scroll-right {
	right: 0;
	padding: 1rem .5rem 1rem 2rem;
}

@media(max-width: $breakpoint) {
	.scroll-button {
		display: none;
	}
}
</style>
