import { onHomeworkFinish, showFireworks,FireworkSettings,playAudio } from "../script/util";
import { defaultData } from "../script/defaultData";

cc.Class({

	extends: cc.Component,

	properties: {
	},

	// 生命周期 onLoad
	onLoad() {
		this.initSceneData();
		this.initSize();
	},

	_imageResList: null,
	_audioResList: null,
	_animaResList: null,
	initSceneData() {
		this._imageResList = [];
		this._audioResList = [];
		this._animaResList = [];
	},

	_designSize: null,  // 设计分辨率
	_frameSize: null,  // 屏幕分辨率
	_mapScaleMin: null,  // 场景中常用缩放（取大值）
	_mapScaleMax: null,  // 场景中常用缩放（取小值）
	_cocosScale: null,  // cocos 自缩放 （较少用到）
	initSize() {
		// 注意cc.winSize只有在适配后(修改fitHeight/fitWidth后)才能获取到正确的值,因此使用cc.getFrameSize()来获取初始的屏幕大小
		let screen_size = cc.view.getFrameSize().width / cc.view.getFrameSize().height
		let design_size = cc.Canvas.instance.designResolution.width / cc.Canvas.instance.designResolution.height
		let f = screen_size >= design_size
		cc.Canvas.instance.fitHeight = f
		cc.Canvas.instance.fitWidth = !f

		const frameSize = cc.view.getFrameSize();
		this._frameSize = frameSize;

		this._designSize = cc.view.getDesignResolutionSize();

		let sx = cc.winSize.width / frameSize.width;
		let sy = cc.winSize.height / frameSize.height;
		this._cocosScale = Math.min(sx, sy);

		sx = frameSize.width / this._designSize.width;
		sy = frameSize.height / this._designSize.height;
		this._mapScaleMin = Math.min(sx, sy) * this._cocosScale;
		this._mapScaleMax = Math.max(sx, sy) * this._cocosScale;
	},


	// 生命周期 start
	start() {
		let getData = this.getData.bind(this);
		if (window && window.courseware) {
			getData = window.courseware.getData;
		}

		getData((data) => {
			console.log('data:', data);
			this.data = data || this.getDefaultData();
			//this.data = this.getDefaultData();
			//this.data = JSON.parse(JSON.stringify(this.data));
			this.preData();
			this.preloadItem()
		})
	},

	preData(){
		let res = JSON.parse(JSON.stringify(this.data));
		let data = [];
		for(let i = 0; i < res.stars.length; i++){
			data[i] = [];
			let pages = this.getArrayByID(res.pages, res.stars[i].id, 'star_id');
			for(let j = 0; j < pages.length; j++){
				data[i][j] = [];
				let kinds = this.getArrayByID(res.kinds, pages[j].id, 'page_id');
				for(let k = 0; k < kinds.length; k++){
					let _kind = {};
					data[i][j][k] = _kind;
					_kind.text = kinds[k].word||"";
					_kind.pic = kinds[k].pic_url||"";
					_kind.audio = kinds[k].audio_url||"";
					_kind.options = [];
					let options = this.getArrayByID(res.options, kinds[k].id, 'kind_id');
					for(let m = 0; m < options.length; m++){
						let _option = {};
						_kind.options[m] = _option;
						_option.text = options[m].word||"";
						_option.pic = options[m].pic_url||"";
						_option.audio = options[m].audio_url||"";
					}
				}
			}
		}

		this.data = {};
		this.data.stars = data;
		console.log(data);
		
	},

	getArrayByID(ar, id, t){
		let ret = [];
		for(let i = 0; i < ar.length; i++){
			if (ar[i][t] == id)
				ret.push(ar[i]);
		}
		return ret;
	},

	getIndexInArray(ar, id){
		for(let i = 0; i < ar.length; i++){
		if (ar[i].id == id){
			return i;
		}
		}
		return -1;
	},
	getData(func) {
		if (window && window.courseware) {
			window.courseware.getData(func, 'scene');
			return;
		}

		const middleLayer = cc.find('middleLayer');
		if (middleLayer) {
			const middleLayerComponent = middleLayer.getComponent('middleLayer');
			middleLayerComponent.getData(func);
			return;
		}

		func(this.getDefaultData());
	},

	getDefaultData() {
		return defaultData;
	},

	preloadItem() {
		this.addPreloadImage();
		this.addPreloadAudio();
		this.addPreloadAnima();
		this.preload();
	},


	addPreloadImage() {

		// this._imageResList.push({ url: this.data.pic_url });
		// this._imageResList.push({ url: this.data.pic_url_2 });
	},

	addPreloadAudio() {

		// this._audioResList.push({ url: this.data.audio_url });
	},

	addPreloadAnima() {

	},

	preload() {

		const preloadArr = this._imageResList.concat(this._audioResList).concat(this._animaResList);
		cc.assetManager.loadAny(preloadArr, null, null, (err, data) => {

			this.loadEnd();
			if (window && window["air"]) {
				window["air"].hideAirClassLoading();
			}

			cc.debug.setDisplayStats(false);
		});
	},


	loadEnd() {
		this.initView();
		this.initButton();
		this.resetData();
	},

	initView() {

		let stars = this.data.stars;
		for(let i = 0; i < stars.length; i++){
			this.addStar();
		}

		console.log(this.data);
		
		this._test = cc.find('Canvas/test');
		this._move_area = cc.find('Canvas/move_area');
		this._kind_group = cc.find('Canvas/fg/kind').getComponent(cc.js.getClassByName('KindGroup'));

		this._move_area.height = this._frameSize.height - 260;
		this._ys = [-this._move_area.height/4, this._move_area.height/4];

		// let option_node = cc.find('res/option');
		// let option = option_node.getComponent(cc.js.getClassByName('WordOption'));

		this._test.on('click', ()=>{

		});

		cc.find('Canvas/add').on('click', ()=>{
			if (this._btn_start.active == true || this._btn_restart.active == true)
				return;
			this.pageFinish();
		});

		cc.find('Canvas/show').on('click', ()=>{

		});



		let selected_node = cc.find('selected');
		let selected = selected_node.getComponent(cc.js.getClassByName('WordOption'));

		this.node.on(cc.Node.EventType.TOUCH_START, (event)=>{
			//console.log(event);
			if (this._touched == true)
				return;
				

			let area = this._move_area;
			for(let i = 0; i < area.childrenCount; i++){
				let option_node = area.children[i];
				let option = option_node.getComponent(cc.js.getClassByName('WordOption'));
				if (this._touched != true && cc.rect(option_node.getBoundingBoxToWorld()).contains(event.touch._point)){
					this.playAudioByName('tap');
					this._moved = false;
					this._touched = true;
					selected.copyValues(option);
					selected.selected(true);
					selected.target = option_node;
					selected.cx = selected.node.x;
					selected.cy = selected.node.y;
					selected.node.position = option_node.parent.convertToWorldSpaceAR(option_node.position);
					selected.offx = selected.node.x - event.touch._point.x;
					selected.offy = selected.node.y - event.touch._point.y;
					option_node.active = false;
					return;
				}
			}

			
		}, this);

        this.node.on(cc.Node.EventType.TOUCH_MOVE, (event)=>{
			if (!this._touched)
				return;
			selected.node.x = event.touch._point.x + selected.offx;
			selected.node.y = event.touch._point.y + selected.offy;

		}, this);

		this.node.on(cc.Node.EventType.TOUCH_CANCEL, (event)=>{
			if (!this._touched)
				return;
			this._moved = true;
			this._touched = false;
			selected.target.active = true;
			selected.node.x = selected.cx;
			selected.node.y = selected.cy;
		}, this);


        this.node.on(cc.Node.EventType.TOUCH_END, (event)=>{
			if (!this._touched)
				return;

			let item, len = this._kind_group.node.childrenCount;
			for(let i = 0; i < len; i++){
				item = this._kind_group.node.children[i];
				if (cc.rect(item.getBoundingBoxToWorld()).intersects(cc.rect(selected.node.getBoundingBoxToWorld()))){
					let kind = item.getComponent(cc.js.getClassByName('WordKind'));
					if (kind.kind_id != selected.kind_id){
						this.playAudioByName('incorrect');
						break;
					}
					this.playAudioByName('correct');
					let node = cc.instantiate(cc.find('res/option_item'));
					let ot = node.getComponent(cc.js.getClassByName('WordOption'));
					ot.copyValues(selected);
					ot.selected(true);
					//node.width *= 0.4;
					//node.height *= 0.4;
					kind.showCorrect(node, ()=>{
						if (this.tryFinish())
							this.pageFinish();
					});
					selected.target.removeFromParent();
					selected.target = null;

					break;
				}
			}
			this._moved = true;
			this._touched = false;
			if (selected.target){
				selected.target.active = true;
				selected.target = null;
			}
			selected.node.x = selected.cx;
			selected.node.y = selected.cy;
		}, this);

	},

	initButton(){
		this._btn_start = cc.find('Canvas/btn_start');
		this._btn_start.on('click', ()=>{
			this.playAudioByName('button');
			this._btn_start.active = false;
			this.updateData();
			this.upForeground(()=>{
				this._moved = true;
				this.playAudioByName('up');
			});
		});
		this._btn_start.active = true;

		this._btn_restart = cc.find('Canvas/btn_restart');
		this._btn_restart.on('click', ()=>{
			this.playAudioByName('button');
			this._btn_restart.active = false;
			// this.downForeground(()=>{
			// 	this._btn_start.active = true;
			// 	this.resetData();
			// });
			this.resetData();
		});
	},

	upForeground(cb){
		let fg = cc.find('Canvas/fg');
		let fg_top = cc.find('Canvas/fg_top').y;
		let fg_bottom = fg_top - 260;
		fg.y = fg_bottom;
		cc.tween(fg)
			.to(0.3, {y :fg_top})
			.call(()=>{
				cb && cb();
			})
			.start();
	},

	downForeground(cb){
		let fg = cc.find('Canvas/fg');
		let fg_top = cc.find('Canvas/fg_top').y;
		let fg_bottom = fg_top - 260;
		fg.y = fg_top;
		cc.tween(fg)
			.to(0.3, {y :fg_bottom})
			.call(()=>{
				cb && cb();
			})
			.start();
	},

	completeAnimation(){
		let base = cc.find('Canvas/firework');
		let items = cc.find('RibbonNodeBase').children;
		
		showFireworks(new FireworkSettings(
			base,
			items,
			cc.v2(0, -400), cc.v2(0, 1000), 200, 200
		));
		showFireworks(new FireworkSettings(
			base,
			items,
			cc.v2(-600, -400), cc.v2(200, 1000), 200, 200
		));
		showFireworks(new FireworkSettings(
			base,
			items,
			cc.v2(600, -400), cc.v2(-200, 1000), 200, 200
		));
	},

    length,
    addStar() {
        if (!this.length) {
            this.length = 0;
        }
        this.length++;
        let length = this.length;

        const starLayout = cc.find('Canvas/layout');
        starLayout.removeAllChildren();
        const paddingY = starLayout.getComponent(cc.Layout).spacingY;

        for (let i = 0; i < length; i++) {
            const starBase = cc.instantiate(cc.find('StarBase'));
            starBase.name = `starBase_${i}`;
            starBase.scale = this.Between(0.5, (starLayout.height / length - paddingY) / starBase.height, 1);
            starBase.parent = starLayout;
        }
        this.currentStarIdx = 0;
	},
	
    currentStarIdx: null,
    showStar(cb) {
        if (!this.currentStarIdx) {
            this.currentStarIdx = 0;
        }

        const starBase = cc.find(`Canvas/layout/starBase_${this.currentStarIdx}`);
        if (!starBase) {
            return;
        }
        const star = starBase.getChildByName('Star');
        const starBig = star.getChildByName('StarBig');
        starBig.scale = 1;
        star.active = true;
        star.scaleX = 0.7 / starBase.scale;
        star.scaleY = 1 / starBase.scale;
        star.angle = 90;
        const canvas = cc.find('Canvas');
        const startPos = this.exchangeNodePos(star.parent, canvas, cc.v2(0, -canvas.height / 2));
        const middlePos = this.exchangeNodePos(star.parent, canvas, cc.v2(0, -canvas.height / 4));
        star.x = startPos.x;
        star.y = startPos.y - starBig.height;

        console.log('middlePos = ' + JSON.stringify(middlePos));
        const time = 1;
        cc.tween(star)
            .to(0.3, { y: middlePos.y + 80 }, { easing: 'quadOut' })
            .to(0.1, { y: middlePos.y + 40, scaleX: 1.2 / starBase.scale, scaleY: 0.8 / starBase.scale }, { easing: 'quadOut' })
            .to(0.1, { y: middlePos.y, scaleX: 1 / starBase.scale, scaleY: 1 / starBase.scale }, { easing: 'quadOut' })
            .delay(0.1)
            .to(0.8, { angle: -720, scale: 1 })
            .start();

        cc.tween(star)
            .delay(0.6)
            .to(0.8, { x: 0 }, { easing: 'quadIn' })
            .start();
        cc.tween(star)
            .delay(0.6)
            .to(0.8, { y: 0 }, { easing: 'quadOut' })
            .start();

        cc.tween(starBig)
            .delay(0.6)
            .to(0.8, { scale: 0 }, { easing: 'quadOut' })
            .call(() => {
                cb && cb();
            })
            .start();

        this.currentStarIdx++;
    },

    Between(a, b, c) {
        return [a, b, c].sort()[1];
    },

    exchangeNodePos(targetNode, baseNode, basePos) {
        return targetNode.convertToNodeSpaceAR(baseNode.convertToWorldSpaceAR(cc.v2(basePos.x, basePos.y)));
    },






















	// ------------------------------------------------

	playAudioByUrl(audio_url, cb = null) {
		if (audio_url) {
			cc.assetManager.loadRemote(audio_url, (err, audioClip) => {
				const audioId = cc.audioEngine.play(audioClip, false, 0.8);
				if (cb) {
					cc.audioEngine.setFinishCallback(audioId, () => {
						cb();
					});
				}
			});
		}
	},

	playAudioByName(audioName) {
		return new Promise((resolve, reject) => {
			try {
				const audioNode = cc.find('res/audio/'+audioName);
				const audioClip = audioNode.getComponent(cc.AudioSource).clip;
				playAudio(audioClip, resolve);
			} catch (e) {
				reject(e);
			}
		});
	},
	// ------------------------------------------

	resetData(){
		let stars = this.data.stars;
		this._star_idx = 0;
		
		let pages = stars[this._star_idx];
		this._page_max = pages.length;
		
		this._page_idx = 0;

		this.currentStarIdx = 0;
		
		let i=0, starBase, star;
		do {
			starBase = cc.find(`Canvas/layout/starBase_${i}`);
        	if (!starBase)
				break;
			star = starBase.getChildByName('Star');
			star.active = false;
			i++;
		} while (1);

		this._btn_start.active = true;
		this._kind_group.node.removeAllChildren();
		this._move_area.removeAllChildren();
	},

	updateData(){
		let pages = this.data.stars[this._star_idx];
		let groups = pages[this._page_idx];

		let kinds = [];
		let options = [];

		let ki, oi;
		for(let i = 0; i < groups.length; i++){
			ki = groups[i];
			let kidx = -1;
			if (ki.text != "" || ki.pic != "" || ki.audio != "" ){
				kidx = i;
				kinds.push({text:ki.text, pic:ki.pic, audio:ki.audio, kind:kidx});
			}
			for(let j = 0; j < ki.options.length; j++){
				oi = ki.options[j];
				options.push({text:oi.text, pic:oi.pic, audio:oi.audio, kind:kidx});
			}
		}

		this._kinds = kinds;
		this._options = options;
		this.updateView();
	},

	updateView(){
		let knode = cc.find('Canvas/fg/kind');
		knode.getComponent(cc.js.getClassByName('KindGroup')).init(this._kinds);
		
		let os = this._options;
		let onode = this._move_area;
		onode.removeAllChildren();

		let ot = cc.find('res/option_item');
		let item, op;
		this._xs = [0, 0];
		for(let i = 0; i < os.length; i++){
			item = cc.instantiate(ot);
			onode.addChild(item);
			op = item.getComponent(cc.js.getClassByName('WordOption'));
			op.init(os[i]);
			console.log(item._w);
			this._xs[i%2] -= (i < 2 ? item._w/2 : item._w);
			item.x = this._xs[i%2];
			console.log(item.x);
			
			item.y  = this._ys[i%2];
		}
		
	},

	pageFinish(){
		this._page_idx ++;
		this.downForeground(()=>{
			if (this._page_idx >= this._page_max){
				this.playAudioByName('star');
				this.playAudioByName('complete');
				this.showStar(()=>{
					this._star_idx ++;
					if (this._star_idx >= this.data.stars.length){
						this.completeTest();
						return;
					}
					this._page_max = this.data.stars[this._star_idx].length;
					this._page_idx = 0;
					this.upForeground(()=>{
						this.updateData();
						this.playAudioByName('up');
					});
				});
			}
			else{
				this.upForeground(()=>{
					this.updateData();
					this.playAudioByName('up');
				});
			}
		});
	},

	completeTest(){
		this.completeAnimation();
		this.playAudioByName('sahua');
		this.playAudioByName('button');
		this.playAudioByName('up');
		this._btn_restart.active = true;
		this._moved = false;
		//this.resetData();
	},

	tryFinish(){
		let item, op, len = this._move_area.childrenCount;
		for(let i = 0; i < len; i++){
			item = this._move_area.children[i];
			op = item.getComponent(cc.js.getClassByName('WordOption'));
			if (op.kind_id >= 0){
				return false;
			}
		}
		return true;
	},

	update (dt) {
		if (!this._moved)
			return;

		let speed = 2;
		let area = this._move_area;
		this._xs[0] += speed;
		this._xs[1] += speed;
		for(let i = 0; i < area.childrenCount; i++){
			let item = area.children[i];
			item.x += speed;

			if (item.x > this._frameSize.width + item._w*1.2){
				this._xs[i%2] -= item._w*1.2;
				item.x = Math.min(-item._w/2, this._xs[i%2]);
			}
		}
	},

});
