class AssetManager
{
    constructor()
    {
        this.onAssetsLoadCompleteCallback = null;
        this.onBackgroundsLoadCompleteCallback = null;

        this.staticMapItems = [];
    }

    get avatarSpriteSheet()
    {
        return this.ssAvatar;
    }

    get balloonSpriteSheet()
    {
        return this.ssBalloon;
    }

    get environmentSpriteSheet()
    {
        return this.ssEnv;
    }

    get itemSpriteSheet()
    {
        return this.ssItems;
    }

    get bgLoader()
    {
        return this.backgroundsLoadQueue;
    }

    loadMapAssets()
    {
        // Load common map assets
		this.spritesLoadQueue = new createjs.LoadQueue();
		this.spritesLoadQueue.addEventListener('complete', () => { this.onMapAssetsLoadComplete(); });

		this.spritesLoadQueue.loadManifest([
	    	{id: 'ssAvatar', src:'assets/images/spritesheet_avatar.png'},
	    	{id: 'ssBalloon', src:'assets/images/spritesheet_balloon.png'},
	    	{id: 'ssEnvironment', src:'assets/images/spritesheet_environment.png'},
	    	{id: 'ssItems', src:'assets/images/spritesheet_items.png'}
	 	]);
    }

    onMapAssetsLoadComplete()
    {
        // Create avatar spritesheet
		this.ssAvatar = new createjs.SpriteSheet({
            images: [this.spritesLoadQueue.getResult('ssAvatar')],
            frames: {width: 30, height: 68, regX: 15, regY: 66},
            animations: {
                avatarE: [0, 19, 'avatarE'],
                avatarN: [20, 38, 'avatarN'],
                avatarNE: [39, 58, 'avatarNE'],
                avatarNW: [59, 78, 'avatarNW'],
                avatarS: [79, 97, 'avatarS'],
                avatarSE: [98, 117, 'avatarSE'],
                avatarSW: [118, 137, 'avatarSW'],
                avatarW: [138, 157, 'avatarW']
            }
        });

		// Create balloon spritesheet
		this.ssBalloon = new createjs.SpriteSheet({
            images: [this.spritesLoadQueue.getResult('ssBalloon')],
            frames: [
                [0, 0, 100, 25],
                [0, 25, 100, 10],
                [0, 35, 100, 10]
            ],
            animations: {
                    balloon_bottom:[0],
                    balloon_middle:[1],
                    balloon_top:[2]
            }
        });

		// Create static items spritesheet
		this.ssEnv = new createjs.SpriteSheet({
            images: [this.spritesLoadQueue.getResult('ssEnvironment')],
            frames: [
                [2, 2, 36, 39],
                [40, 2, 46, 67],
                [88, 2, 44, 80],
                [134, 2, 137, 143],
                [273, 2, 43, 130],
                [318, 2, 142, 139]
            ],
            animations: {
                bush1: [0],
                bush4: [1],
                door:  [2],
                tree2: [3],
                tree3: [4],
                tree4: [5]
            }
        });

		// Create dynamic items spritesheet
		this.ssItems = new createjs.SpriteSheet({
            images: [this.spritesLoadQueue.getResult('ssItems')],
            frames: {width: 52, height: 58, regX: 18, regY: 44},
            animations: {
                barrel: [0, 1, 'barrel']
            }
        });

        if (this.onAssetsLoadCompleteCallback != null)
            this.onAssetsLoadCompleteCallback();
        else
            console.error('Missing onAssetsLoadComplete callback')
    }

    loadMapBackgrounds(bgLoaderManifest)
    {
        // Load map backgrounds
        this.backgroundsLoadQueue = new createjs.LoadQueue();
        this.backgroundsLoadQueue.addEventListener('complete', () => { this.onMapBackgroundsLoadComplete(); });

        this.backgroundsLoadQueue.loadManifest(bgLoaderManifest);
    }

    onMapBackgroundsLoadComplete()
    {
        if (this.onBackgroundsLoadCompleteCallback != null)
            this.onBackgroundsLoadCompleteCallback();
        else
            console.error('Missing onBackgroundsLoadComplete callback')
    }

    buildStaticMapItems(roomId, setupObj)
    {
        const items = [];

        for (let itemId of setupObj.getKeys())
        {
            const item = {};

            const itemData = setupObj.get(itemId); // SFSObject

            // Create sprite
            const sprite = new createjs.Sprite(this.environmentSpriteSheet);
            sprite.gotoAndStop(itemId);
            sprite.regX = itemData.get('rx');
            sprite.regY = itemData.get('ry');

            item.sprite = sprite;

            // List sprite instances coordinates
            const coordinates = [];
            const coordsArray = itemData.get('coords'); // Int array

            for (let c = 0; c < coordsArray.length; c += 2)
            {
                let x = coordsArray[c];
                let y = coordsArray[c+1];

                coordinates.push([x,y]);
            }

            item.coordinates = coordinates;

            items[itemId] = item;
        }

        this.staticMapItems[roomId] = items;
    }

    getStaticMapItems(roomId)
    {
        return this.staticMapItems[roomId];
    }
}

export default new AssetManager();