import { _decorator, Color, Component, instantiate, Label, Node, Prefab, Size, Slider, Sprite, Toggle, tween, Tween, UIOpacity, UITransform, Vec3 } from 'cc';
import { ani_frame, att_ani_data } from '../../../data/data';
import { frame_item } from './frame_item';
import { new_frame } from './new_frame';
import { Attributes } from '../Attributes';
import { tools } from '../../tools';
import { opt_frame } from './opt_frame';
import { control } from '../control';
import { gameManager } from '../../run/gameManager';
const { ccclass, property } = _decorator;

@ccclass('edit_animation')
export class edit_animation extends Component {
    @property(Node) ani_sf:Node = null;
    @property(Node) btn_new_ani_frame:Node = null;
    @property(Node) btn_save:Node = null;
    @property(Node) btn_run:Node = null;
    @property(Node) frame_content:Node  = null;
    @property(Prefab) item_prefab:Prefab = null;
    @property(Node) new_frame:Node = null;
    @property(Node) btn_close:Node = null;
    @property(Slider) slider_scale:Slider = null;
    @property(Node) lab_slider:Node = null;
    @property(Node) opt_frame:Node = null;
    @property(Node) lab_run_status:Node = null;
    @property(Node) toggle_loop:Node = null;
    @property(Node) toggle_move:Node = null;
    private m_data:att_ani_data = null;
    private play_status:boolean = false;
    public initView(){
        this.new_frame.getComponent(new_frame).initView(this.onCreateFrame.bind(this),this.onUpdateFrame.bind(this))
        this.opt_frame.getComponent(opt_frame).initView(this.onClickDelete.bind(this),this.onClickEdit.bind(this))
        this.btn_new_ani_frame.on(Node.EventType.TOUCH_END,()=>{
            if(!this.play_status){
                let up_frame = this.m_data.ani_frame_list.length>0?this.m_data.ani_frame_list[this.m_data.ani_frame_list.length-1]:null
                this.new_frame.getComponent(new_frame).show(up_frame);
            }
        })
        if(this.m_data.isMove==undefined||this.m_data.isMove == null){
            this.m_data.isMove = true;
        }

        this.toggle_move.on('toggle',()=>{
            this.m_data.isMove = this.toggle_move.getComponent(Toggle).isChecked;
        })

        this.toggle_loop.on('toggle',()=>{
            Tween.stopAll()
            this.lab_run_status.getComponent(Label).string = "运行"
            this.play_status = false;
            this.unSelectAllItem()
            this.m_data.isLoop = this.toggle_loop.getComponent(Toggle).isChecked;
        })
        this.toggle_loop.getComponent(Toggle).isChecked =  this.m_data.isLoop
        this.toggle_move.getComponent(Toggle).isChecked =  this.m_data.isMove
        this.btn_close.on(Node.EventType.TOUCH_END,()=>{
            if(!this.play_status){
                this.node.active = false;
            }
        })
        this.btn_save.on(Node.EventType.TOUCH_END, ()=> {
            gameManager.requestSaveEditScene()
        })
        this.btn_run.on(Node.EventType.TOUCH_END,()=>{
            if(this.m_data.ani_frame_list.length<2){
                return tools.showToast("动画不能低于2帧")
            }
            if(!this.play_status){
                this.play_status = true;
                this.lab_run_status.getComponent(Label).string = "停止"
                this.runAnimation()
            }else{
                Tween.stopAll()
                this.lab_run_status.getComponent(Label).string = "运行"
                this.play_status = false;
                this.unSelectAllItem()
            }
 
        })
        this.onSlider()
    }   

    runAnimation(){
        Tween.stopAll()
        let getFrameData = (index)=>{
            this.updateFrameItemSelectStatus(index)
            let cur_frame:ani_frame =this.m_data.ani_frame_list[index];
            let up_frame:ani_frame = index>0?this.m_data.ani_frame_list[index-1]:this.m_data.ani_frame_list[0];
            return {"cur_frame":cur_frame,"up_frame":up_frame}
        }
        let cur_index = 0;
        let data = getFrameData(cur_index);
        let call_back = ()=>{
            cur_index++;
            if(cur_index>=this.m_data.ani_frame_list.length){
                if(this.m_data.isLoop){
                    cur_index = 0;
                }else{
                    this.play_status = false;
                    this.lab_run_status.getComponent(Label).string = "运行"
                    this.unSelectAllItem()
                    return;
                }
            }
            let data = getFrameData(cur_index);
            this.runFrame(data.cur_frame,data.up_frame,call_back)
        }
        this.runFrame(data.cur_frame,data.up_frame,call_back)
        
    }



    runFrame(frame:ani_frame,up_frame:ani_frame,call){
        let self = this;
        let tweenDuration: number = frame.next_time;
        let origin_x = self.m_data.ani_frame_list[0].pos_x;
        let origin_y = self.m_data.ani_frame_list[0].pos_y
        this.ani_sf.getComponent(Sprite).spriteFrame = control.res_map.get(frame.url_name)
        let n_pos:Vec3 = new Vec3(frame.pos_x-origin_x,frame.pos_y-origin_y)
        let _color = new Color()
        _color = _color.fromHEX(frame.color)
        
        class BindTarget{
            color : Color;
            opacity:number;
            size:Size;
            pos:Vec3;
            rotation:number;
            anchorPointX:number;
            anchorPointY:number;
        }
        let bindTarget : BindTarget = new BindTarget();
        let rotation = up_frame.rotation == undefined?0:up_frame.rotation
        bindTarget.rotation = rotation
        bindTarget.color = new Color().fromHEX(up_frame.color)
        bindTarget.opacity = up_frame.transparent;
        bindTarget.size = new Size(up_frame.size_width,up_frame.size_height)
        bindTarget.pos = new Vec3(up_frame.pos_x-origin_x,up_frame.pos_y-origin_y)
        bindTarget.anchorPointX = up_frame.anchor_point_x==undefined?0.5:up_frame.anchor_point_x
        bindTarget.anchorPointY = up_frame.anchor_point_y==undefined?0.5:up_frame.anchor_point_y
        let color_opactiy_tw_size = tween(bindTarget)
        .to( tweenDuration, { pos:n_pos,color: _color,opacity:frame.transparent,size:new Size(frame.size_width,frame.size_height),rotation:frame.rotation, anchorPointX:frame.anchor_point_x, anchorPointY:frame.anchor_point_y }, {
            onUpdate(tar:BindTarget){
                self.ani_sf.getComponent(Sprite).color = tar.color; 
                self.ani_sf.getComponent(UIOpacity).opacity = tar.opacity;
                self.ani_sf.getComponent(UITransform).setContentSize(tar.size)
                self.ani_sf.position = tar.pos
                self.ani_sf.angle = tar.rotation;
                self.ani_sf.getComponent(UITransform).setAnchorPoint(tar.anchorPointX, tar.anchorPointY)
            }
        }).call(()=>{
            call()
        });
        color_opactiy_tw_size.start();

    }

    onSlider(){
        this.ani_sf.scale = new Vec3( this.slider_scale.progress, this.slider_scale.progress)
        this.lab_slider.getComponent(Label).string =  `显示缩放：${ this.slider_scale.progress.toFixed(3)}`
    }

    protected start(): void {
        this.initView()   
    }

    public show(data:att_ani_data){
        this.node.active = true;
        this.m_data = data;
        this.updateFrameList()
    }

    updateFrameList(){
        this.frame_content.removeAllChildren()
        for (let index = 0; index < this.m_data.ani_frame_list.length; index++) {
            const element = this.m_data.ani_frame_list[index];
            this.addFrameOnList(element,index)
        }
        this.updateFirstFrameStatus()
    }

    updateFirstFrameStatus(){
        if(this.m_data.ani_frame_list.length>0){
            let frame =  this.m_data.ani_frame_list[0];
            this.ani_sf.getComponent(Sprite).spriteFrame = control.res_map.get(frame.url_name)
            this.ani_sf.getComponent(UITransform).contentSize = new Size(frame.size_width,frame.size_height);
        }else{
            let att = Attributes.Singleton.get_cur_att_data()
            this.ani_sf.getComponent(Sprite).spriteFrame = control.res_map.get(att.src_name)
            this.ani_sf.getComponent(UITransform).contentSize = new Size(att.width,att.height);
        }
    }

    onClickDelete(item:frame_item){
        tools.show_dialog(`是否删除第${item.getIndex()}帧`,()=>{
            this.m_data.ani_frame_list.splice(item.getIndex(),1)
            item.node.removeFromParent()
            this.updateFrameList()
        })
    }

    onUpdateFrame(){
        this.updateFrameList()
    }

    onClickEdit(item:frame_item){
        //  let up_frame = item.getIndex()>0?this.m_data.ani_frame_list[item.getIndex()-1]:null
        //  this.new_frame.getComponent(new_frame).show_edit(item,up_frame);
        console.log('item.getIndex()=',item.getIndex())
        let up_frame = null;
        if(item.getIndex()>=0) {
            up_frame = this.m_data.ani_frame_list[item.getIndex()]
        }
        this.new_frame.getComponent(new_frame).show_edit(item,up_frame);
    }

    unSelectAllItem(){
        for (let index = 0; index < this.frame_content.children.length; index++) {
            const element = this.frame_content.children[index];
            element.getComponent(frame_item).unSelectStatus()
        }
    }

    updateFrameItemSelectStatus(i:number){
        for (let index = 0; index < this.frame_content.children.length; index++) {
            const element = this.frame_content.children[index];
            if(i===index){
                element.getComponent(frame_item).selectStatus()
            }else{
                element.getComponent(frame_item).unSelectStatus()
            }
        }
    }
    onClickFrame(item:frame_item){
        this.opt_frame.getComponent(opt_frame).show(item)
    }

    addFrameOnList(frame:ani_frame,index:number){
        let item = instantiate(this.item_prefab)
        item.parent = this.frame_content;
        item.getComponent(frame_item).initView(frame,this.onClickFrame.bind(this),index)
    }

    onCreateFrame(frame:ani_frame){
        console.log('this.m_data.ani_frame_list=',this.m_data.ani_frame_list)
        this.addFrameOnList(frame,this.m_data.ani_frame_list.length)
        this.m_data.ani_frame_list.push(frame)
        this.updateFirstFrameStatus()
    }
}


