import { _decorator, Component, log, math, Node } from 'cc';
import { YXCollectionView, YXIndexPath, YXLayout, YXLayoutAttributes } from '../lib';
const { ccclass, property } = _decorator;

@ccclass('yx_card_page_layout')
export class YXCardPageLayout extends YXLayout {

    /**
     * 节点大小
     */
    itemSize: math.Size = null

    /**
     * 最多同时显示多少个节点
     */
    maxVisibleItemCount: number = 4

    /**
     * 每个节点之间的缩放差距
     */
    eachScale: number = 0.1

    /**
     * 每个节点之间间距
     */
    eachSpacing: number = 50

    /**
     * 整体内容偏移
     */
    contentOffset: math.Vec3 = null

    /**
     * 此类布局必须确定节点大小
     */
    constructor(itemSize: math.Size) {
        super()
        this.itemSize = itemSize
    }

    prepare(collectionView: YXCollectionView): void {
        collectionView.scrollView.horizontal = true
        collectionView.scrollView.vertical = false

        let allAttributes = []
        let total = collectionView.numberOfItems instanceof Function ? collectionView.numberOfItems(0, collectionView) : collectionView.numberOfItems
        total = Math.min(total, this.maxVisibleItemCount)
        for (let index = 0; index < total; index++) {
            let attr = new YXLayoutAttributes()
            attr.indexPath = new YXIndexPath(0, index)
            attr.frame = new math.Rect()
            attr.frame.size = this.itemSize
            allAttributes.push(attr)
        }
        this.attributes = allAttributes
        let contentSize = collectionView.scrollView.view.contentSize.clone()
        contentSize.width = contentSize.width * 3
        this.contentSize = contentSize
    }

    layoutAttributesForElementsInRect(rect: math.Rect, collectionView: YXCollectionView): YXLayoutAttributes[] {
        let offset = collectionView.scrollView.getScrollOffset()
        offset.x = - offset.x
        let progress = (offset.x - collectionView.scrollView.view.width) / collectionView.scrollView.view.width // [ -1 0 1 ]

        for (let index = 0; index < this.attributes.length; index++) {
            const attr = this.attributes[index];

            // 调整层级
            attr.zIndex = -index

            // 调整位置
            let startOffsetY = index * this.eachSpacing
            attr.frame.x = offset.x + (collectionView.scrollView.view.width - attr.frame.width) * 0.5
            attr.frame.y = offset.y + (collectionView.scrollView.view.height - attr.frame.height) * 0.5 + startOffsetY
            attr.frame.y = attr.frame.y - this.eachSpacing * Math.abs(progress)
            attr.frame.y = Math.max(attr.frame.y, offset.y + (collectionView.scrollView.view.height - attr.frame.height) * 0.5)
            if (index == 0) {
                attr.frame.x = attr.frame.x - progress * collectionView.scrollView.view.width
            }

            // 调整缩放
            let startScale = 1 - index * this.eachScale
            let scale = startScale
            scale = scale + this.eachScale * Math.abs(progress)
            scale = Math.min(scale, 1)
            attr.scale = new math.Vec3(scale, scale, 1)

            // 偏移
            if (this.contentOffset) {
                attr.offset = this.contentOffset
            }
        }
        return this.attributes
    }

    initOffset(collectionView: YXCollectionView): void {
        let offset = new math.Vec2()
        offset.x = collectionView.scrollView.view.width
        offset.y = 0
        collectionView.scrollView.scrollToOffset(offset)
    }

    /**
     * 分页逻辑
     */
    targetOffset(collectionView: YXCollectionView, touchMoveVelocity: math.Vec3, startOffset: math.Vec2): { offset: math.Vec2; time: number; } {
        let offset = collectionView.scrollView.getScrollOffset()
        offset.x = - offset.x
        let threshold = 0.2

        let idx = Math.round(offset.x / collectionView.scrollView.view.width)
        let r = touchMoveVelocity.x / collectionView.scrollView.view.width
        if (startOffset && Math.abs(r) >= threshold) {
            idx = Math.round(startOffset.x / collectionView.scrollView.view.width) + (r > 0 ? -1 : 1)
        }
        offset.x = idx * collectionView.scrollView.view.width

        return { offset: offset, time: 0.5 }
    }

    /**
     * 标记此布局需要实时更新
     */
    shouldUpdateAttributesForBoundsChange(): boolean {
        return true
    }

    /**
     * 标记此布局需要调整节点层级
     */
    shouldUpdateAttributesZIndex(): boolean {
        return true
    }
}

