/* Globals */
var config;

function exerciseOnInit(_config) {
    config = _config;
    exerciseReady();
}

function showExercise() {
    setTimeout(function() {
        showMessage(getOrderInfo(), 'Instrukcja');
    }, 500);
}

function exerciseOnStart() {
    hideAllElements(config.container, 'instance');
    switch (config.type) {
        case 'drag':
            setDragAndDrop(config);
            break;
        case 'dragdice':
            setDragDice(config);
            break;
        case 'input':
            setInput(config);
            break;
        case 'memo':
            setMemo(config);
            break;
        case 'paint':
            setPaint(config);
            break;
        case 'paintdice':
            setPaintDice(config);
            break;
        case 'paintdice2':
            setPaintDice2(config);
            break;
        case 'rope':
            setRope(config);
            break;
        case 'select':
            setSelect(config);
            break;
        case 'sortX':
            setSortable(config, 'x');
            break;
        case 'sortY':
            setSortable(config, 'y');
            break;
    }
    showAllElements(config.container, 'instance', 0);
    setSounds(config);
}

function exerciseGoodAnswer() {
    //console.log('Dobrze');
    playSound('ssGoodAnswer');
}
function exerciseBadAnswer() {
    //console.log('Źle');
    playSound('ssBadAnswer');
}
function exerciseOnComplete() {
    if (typeof config.endsound !== 'undefined') {
        if (config.endsound !== null) {
            playSound(config.endsound);
        }
    }
    else {
        playSound('ssFanfary');
    }
    loadFeedbackAnimation();
}
function exerciseCheck(container, prefix, callback) {
    var isCorrect = false;
    for (var name in container) {
        if (name.indexOf(prefix) > -1) {
            var item = container[name];
            if (item.correct === true) {
                isCorrect = true;
            }
            else {
                isCorrect = false;
                break;
            }
        }
    }

    if (isCorrect === true) {
        if (typeof callback === 'function')
            callback();
        exerciseOnComplete();
    }
}
function getChildrenNum(obj, name) {
    var num = 0;
    for (var p in obj) {
        //if (obj.hasOwnProperty(p)) {
        if (p.indexOf(name) !== -1) {
            num++;
        }
    }
    return num;
}
function getDistance(point1, point2) {
    var xx = point2.x - point1.x;
    var yy = point2.y - point1.y;
    return Math.sqrt(xx * xx + yy * yy);
}
function getPromptValue(msg, callback) {
    var correct = false;
    var value;
    if (typeof callback === 'function') {
        /*
         
         if(typeof msg !== 'undefined')
         $('#modal .modal-title').html(msg);
         $('#modal .modal-body').html('<input type="text" class="modal-input form-control">');
         $('#modal').modal('show');
         $('#modal').on('hidden.bs.modal', function (e) {
         correct = callback($('#modal .modal-input').val());
         if(correct === false) {
         $('#modal .modal-body').html('<input type="text" class="modal-input form-control">');
         $('#modal').modal('show');				
         }
         })*/
        while (correct === false) {
            value = prompt(msg, '');
            correct = callback(value);
        }
    }
    else {
        value = prompt(msg, '');
    }
    return value;


}
function getRandomNum(min, max) {
    return Math.floor(Math.random() * (max - min + 1) + min);
}
function getRgbToHex(r, g, b) {
    return "#" + ((1 << 24) + (r << 16) + (g << 8) + b).toString(16).slice(1);
}
function playSound(val) {
    //console.log('playSound: ' + val);
    var sound = createjs.Sound.play(val);
    //console.log(sound);
    /*
    if (val.indexOf('.mp3') > -1 || val.indexOf('.ogg') > -1) {
        //createjs.Sound.play(getAssetDir() + '/sounds/' + val);
    }
    else {
        var instance = createjs.Sound.play(val, createjs.Sound.INTERRUPT_NONE, 0, 0, false, 1);
        //createjs.Sound.play(val);
    }
    */
}

function playHtml5Sound(val){
	//if (val.indexOf('.mp3') == -1 && val.indexOf('.ogg') == -1) 
            //val +='.mp3';
	playSound(val);
}

function playSoundCustom(obj) {
    //console.log(obj.parent.id);
}

function hideAllElements(container, prefix, callback) {
    for (var instance in container) {
        if (instance.indexOf(prefix) > -1) {
            container[instance].orga = container[instance].alpha
            container[instance].alpha = 0;
        }
    }

    if (typeof callback === 'function') {
        callback();
    }
}
function moveOutAllElements(container, prefix, pos, callback) {
    for (var instance in container) {
        if (instance.indexOf(prefix) > -1) {
            container[instance].orgx = container[instance].x;
            container[instance].orgy = container[instance].y;
            if (typeof pos.x === 'number')
                container[instance].x = pos.x;
            if (typeof pos.y === 'number')
                container[instance].y = pos.y;
        }
    }

    if (typeof callback === 'function') {
        callback();
    }
}
function moveInAllElements(container, prefix, pause, easetype, callback) {
    var d = 0;
    var t = 0.2;
    for (var instance in container) {
        if (instance.indexOf(prefix) > -1) {
            d++;
            if (typeof easetype !== 'undefined') {
                TweenMax.to(container[instance], 0.5, {
                    delay: pause + d * t,
                    alpha: 1,
                    x: container[instance].orgx,
                    y: container[instance].orgy,
                    ease: easetype,
                    onCompleteParams: [d],
                    onComplete: function() {
                        var last = this.vars.onCompleteParams[0];
                        if (typeof callback === 'function' && last === getChildrenNum(container, prefix) - 2) {
                            callback();
                        }
                    },
                });
            }
            else {
                TweenMax.to(container[instance], 0.5, {
                    delay: pause + d * t,
                    alpha: 1,
                    x: container[instance].orgx,
                    y: container[instance].orgy,
                    onCompleteParams: [d],
                    onComplete: function() {
                        var last = this.vars.onCompleteParams[0];
                        if (typeof callback === 'function' && last === getChildrenNum(container, prefix)) {
                            callback();
                        }
                    }
                });
            }


        }
    }
}
function showAllElements(container, prefix, pause, timedelay, callback) {
    var d = 0;
    var t = 0.2;
    if (typeof timedelay !== undefined)
        t = timedelay;
    for (var instance in container) {
        if (instance.indexOf(prefix) !== -1) {
            d++;
            TweenMax.to(container[instance], 0.5, {
                delay: pause + d * t,
                alpha: container[instance].orga,
            });
        }
    }

    if (typeof callback === 'function') {
        callback();
    }
}
function showMessage(msg, title, callback) {
    //alert(msg);
    if (typeof title !== 'undefined')
        $('#modal .modal-title').html(title);
    $('#modal .modal-body').html(msg);
    $('#modal').modal('show');
    if (typeof callback === 'function') {
        callback();
    }
}
function setGroupName(container, groups, prefix) {
    for (var group in groups) {
        for (var item in groups[group]) {
            var name = prefix + groups[group][item];
            var obj = container[name];
            if (typeof (obj) !== 'undefined') {
                obj.gname = group;
            }
        }
    }
}

//==============================================================================//
/* Custom */
//==============================================================================//

/*Drag And Drop*/
function setDragAndDrop(config) {
    var exerciseContainer = config.container;
    exerciseContainer.id = config.id;

    var dragGroups = config.groups = config.groupdrags;
    var dragNamePrefix = config.prefix;

    var dropGroups = config.groupdrops;
    var dropNamePrefix = config.prefix2;

    var dragDropResults = config.results;

    var dragDropRange = 100;
    if (typeof (config.range) !== 'undefined')
        dragDropRange = config.range;

    var dragDropAlpha = 0;
    if (typeof (config.alpha) !== 'undefined')
        dragDropAlpha = config.alpha;

    var dragDropAlpha2 = 0.6;
    if (typeof (config.alpha2) !== 'undefined')
        dragDropAlpha2 = config.alpha2;

    var dragDropRotationAuto = false;
    if (typeof (config.rotation) !== 'undefined')
        dragDropRotationAuto = config.rotation;

    var dragDropSizeAuto = false;
    if (typeof (config.size) !== 'undefined')
        dragDropSizeAuto = config.size;

    var dragDropScale = false;
    if (typeof (config.scale) !== 'undefined')
        dragDropScale = config.scale;

    //Dodatkowe parametry zdefiniowane w pliku .fla
    if (typeof (config.exerciseAfterInit) !== 'undefined' && typeof (config.exerciseAfterInit) === 'function') {
        config.exerciseAfterInit(exerciseContainer);
    }


    var dragNum = getChildrenNum(exerciseContainer, dragNamePrefix);
    var dropNum = getChildrenNum(exerciseContainer, dropNamePrefix);

    //Set group names
    if (typeof (dragGroups) !== 'undefined') {
        setGroupName(exerciseContainer, dragGroups, dragNamePrefix);
    }

    if (typeof (dropGroups) !== 'undefined') {
        setGroupName(exerciseContainer, dropGroups, dropNamePrefix);
    }

    //Set drops
    for (var h = 0; h < dropNum; h++) {
        var dropName = dropNamePrefix + (h + 1);
        var dropItem = exerciseContainer[dropName];
        dropItem.alpha = dragDropAlpha;
    }

    //Set drags properties
    for (var i = 0; i < dragNum; i++) {
        var dragName = dragNamePrefix + (i + 1);
        var drag = exerciseContainer[dragName];
        if (drag) {
            drag.cursor = 'pointer';
            drag.dragable = true;
            drag.name = dragName;            
            drag.orgx = exerciseContainer[dragName].x;
            drag.orgy = exerciseContainer[dragName].y;
            drag.orgr = exerciseContainer[dragName].rotation;
            drag.orgsx = exerciseContainer[dragName].scaleX;
            drag.orgsy = exerciseContainer[dragName].scaleY;

            drag.on('mousedown', function(e) {
                this.offset = {
                    x: this.x - e.stageX,
                    y: this.y - e.stageY
                };

                if (typeof (this.orgz) === 'undefined')
                    this.orgz = exerciseContainer.getChildIndex(this);

                if (typeof (exerciseContainer[this.dropname]) !== 'undefined') {
                    exerciseContainer[this.dropname].isdrop = false;
                    exerciseContainer[this.dropname].correct = false;
                    delete exerciseContainer[this.dropname].dragname;
                    delete exerciseContainer[this.dropname].draggroup;
                }

                delete this.dropname;

                //Przeun obiektu na gore.
                exerciseContainer.addChildAt(this, exerciseContainer.getNumChildren() - 1);
                //playSound('ssDrag');
            });

            drag.on('pressmove', function(e) {
                if(this.dragable === true) {
                    this.x = e.stageX + this.offset.x;
                    this.y = e.stageY + this.offset.y;
                }

                for (var j = 0; j < dropNum; j++) {
                    var dropName = dropNamePrefix + (j + 1);
                    var dropItem = this.parent[dropName];
                    TweenMax.to(dropItem, 0.2, {alpha: dragDropAlpha});

                    if (dropItem && dragInRange(this, dropItem, dragDropRange)) {
                        TweenMax.to(dropItem, 0.2, {alpha: dragDropAlpha2});
                    }
                    else {
                        TweenMax.to(dropItem, 0.2, {alpha: dragDropAlpha});
                    }
                }
            });

            drag.on('pressup', function(e) {
                var isDropped = false;
                var dropNames = getClosetsDrops(exerciseContainer, dropNamePrefix, this);

                for (var j = 0; j < dropNum; j++) {
                    var dropName = dropNames[j][0];
                    var dropIndex = dropName.replace(dropNamePrefix, '') - 1;
                    var dropItem = exerciseContainer[dropName];

                    if (dropItem && dragInRange(this, dropItem, dragDropRange) && dropItem.isdrop !== true) {
                        this.dropname = dropName;
                        isDropped = true;
                        dropItem.isdrop = true;
                        dropItem.dragname = this.name;
                        dropItem.draggroup = this.gname;
                        dropItem.correct = dropCheck(config, this, dropIndex);

                        TweenMax.to(this, 0.2, {
                            x: dropItem.x,
                            y: dropItem.y,
                            ease: Back.easeOut,
                            onComplete: function() {
                                exerciseCheck(exerciseContainer, dropNamePrefix, dropNum);
                            }
                        });

                        //Alpha
                        TweenMax.to(dropItem, 0.2, {alpha: dragDropAlpha});

                        //Auto Rotation
                        if (dropItem.correct === true && (dragDropRotationAuto === true || dragDropRotationAuto === 'auto')) {
                            var tmpRotation = dropItem.rotation;
                            TweenMax.to(this, 0.2, {rotation: tmpRotation, ease: Back.easeOut});
                        }

                        //Custom Rotation
                        if (typeof (dropItem.rotate) !== 'undefined')
                            TweenMax.to(this, 0.2, {rotation: dropItem.rotate, ease: Back.easeOut});

                        if (typeof (this.rotate) !== 'undefined')
                            TweenMax.to(this, 0.2, {rotation: this.rotate, ease: Back.easeOut});

                        //Auto Scale
                        if (dropItem.correct === true && (dragDropSizeAuto === true || dragDropSizeAuto === 'auto')) {
                            var tmpScaleX = dropItem.getBounds().width / this.getBounds().width;
                            var tmpScaleY = dropItem.getBounds().height / this.getBounds().height;
                            TweenMax.to(this, 0.2, {scaleX: tmpScaleX, scaleY: tmpScaleY, ease: Back.easeOut, });
                        }

                        //Custom Scale
                        if (dragDropScale !== false && typeof (dragDropScale) === 'number') {
                            TweenMax.to(this, 0.2, {scaleX: dragDropScale, scaleY: dragDropScale, ease: Back.easeOut, });
                        }
                        TweenMax.to(dropItem, 0.2, {alpha: dragDropAlpha});

                        //zIndex
                        if (typeof (config.zindex) !== 'undefined')
                            exerciseContainer.addChildAt(this, config.zindex);

                        break;
                    }
                }

                if (isDropped === false) {
                    TweenMax.to(this, 0.3, {
                        x: this.orgx,
                        y: this.orgy,
                        rotation: this.orgr,
                        scaleX: this.orgsx,
                        scaleY: this.orgsy,
                        ease: Back.easeOut
                    });
                    //Ustaw poczatkowa glebokosc
                    exerciseContainer.addChildAt(this, this.orgz);
                }
            });
        }
    }

    //Dodatkowa funkcjonalności zdefiniowane w pliku .fla
    if (typeof (config.exerciseBeforeFinish) !== 'undefined' && typeof (config.exerciseBeforeFinish) === 'function') {
        config.exerciseBeforeFinish(exerciseContainer);
    }
}
function dragInRange(drag, drop, range) {
    if (drag.x > drop.x - drop.getBounds().width / 2 - range &&
            drag.x < drop.x + drop.getBounds().width / 2 + range &&
            drag.y > drop.y - drop.getBounds().height / 2 - range &&
            drag.y < drop.y + drop.getBounds().height / 2 + range) {
        return true;
    }
    return false;
}
function dropCheck(config, dragCurrent, dropIndex) {
    var exerciseContainer = config.container;
    var dragNamePrefix = config.prefix;
    var dropNamePrefix = config.prefix2;
    var dropGroupName = exerciseContainer[dropNamePrefix + (dropIndex + 1)].gname;
    var dragDropResults = config.results;
    var dragDropResultsTmp;
    var isCorrect = false;
    var isInGroup = false;
    //Grupa
    if (typeof (dragCurrent.gname) !== 'undefined') {
        // Wariant warunkowy
        if ((dragDropResults[dropIndex]).indexOf('|') > 0) {
            dragDropResultsTmp = dragDropResults[dropIndex].split('|');
            for (var dropId in dragDropResultsTmp) {
                //Jeżeli nazwa grupy draga jest jednym z elementów tablicy odpowiedzi
                if (dragCurrent.gname === dragDropResultsTmp[dropId]) {
                    //Jeżeli drop jest przypisany do grupy oraz jeżeli tej do grupy dropów został już dodany obiekt z określonej grupy dragów.
                    if (typeof (dropGroupName) !== 'undefined') {
                        var groupDrops = getGroupDrops(exerciseContainer, dropNamePrefix, dragCurrent, dropGroupName);
                        for (var dropId2 in groupDrops) {
                            if (dragCurrent.gname === groupDrops[dropId2].draggroup && dragCurrent.name !== groupDrops[dropId2].dragname) {
                                isInGroup = true;
                                break;
                            }
                        }
                        //Jeżeli w grupie dropów nie ma żadnego elementu z grupy dragów. Odpowiedź poprawna.
                        if (isInGroup === false) {
                            isCorrect = true;
                            break;
                        }
                        //Jeżeli w grupie dropów jest już jakiś element z grupy dragów. Odpowiedź niepoprawna.
                        else {
                            isCorrect = false;
                        }
                    }
                    //Jeżeli nie grupy dropów, a drop znajduje się na liście odpowiedzi. Odpowiedź poprawna.
                    else {
                        isCorrect = true;
                        break;
                    }
                }
                //Jeżeli drop nie znajduje się na liście odpowiedzi. Odpowiedź poprawna.
                else {
                    isCorrect = false;
                }
            }
        }
        // Pozostale warianty
        else {
            //Jeżeli nazwa grupy draga jest taka sama jak z element z tablicy odpowiedzi
            if (dragCurrent.gname === dragDropResults[dropIndex]) {
                isCorrect = true;
                //exerciseGoodAnswer();
                //return true;
            }
            else {
                isCorrect = false;
                //exerciseBadAnswer();
                //return false;
            }
        }
    }
    //Pojedynczy element
    else {
        //Wariant warunkowy
        if ((dragDropResults[dropIndex]).indexOf('|') > 0) {
            dragDropResultsTmp = dragDropResults[dropIndex].split('|');
            for (var dropId in dragDropResultsTmp) {
                //Jeżeli drag jest jedym z elementów tablicy odpowiedzi
                if (dragCurrent.name === dragNamePrefix + dragDropResultsTmp[dropId]) {
                    isCorrect = true;
                    break;
                }
                else {
                    isCorrect = false;
                }
            }
        }
        //Pozostale warianty
        else {
            //Jeżeli drag jest taka sama jak z element z tablicy odpowiedzi
            if (dragCurrent.name === dragNamePrefix + dragDropResults[dropIndex]) {
                isCorrect = true;
                //exerciseGoodAnswer();
                //return true;
            }
            else {
                isCorrect = false;
                //exerciseBadAnswer();
                //return false;
            }
        }
    }

    //Dodatkowy warunek zdefiniowan w pliku .fla w zmiennej config
    if (typeof config.exerciseExtraCheck === 'function') {
        var isCorrectCustom = config.exerciseExtraCheck(config, dragCurrent, dropIndex, isCorrect);

        if (typeof isCorrectCustom !== 'undefined') {
            isCorrect = isCorrectCustom;
        }
    }

    if (isCorrect === true) {
        exerciseGoodAnswer();
        return true;
    }
    else {
        exerciseBadAnswer();
        return false;
    }
}
function dropPairCheck(config, dragCurrent, dropIndex, isCorrect) {
	//console.log(dragCurrent, dropIndex, isCorrect);
	dragIndex = dragCurrent.name;
	dragIndex = dragIndex.split('_')[1];
	
	if(dragIndex % 2 == 0) {
		dragEven = true;
		dragOdd = false;
	}
	else {
		dragEven = false;
		dragOdd = true;
	}
	
	if(dropIndex % 2 == 0) {
		dropOdd = false;
		dropEven = true;
	}
	else {
		dropOdd = true;
		dropEven = false;
	}
	
	if(dragOdd === dropOdd || dragEven === dropEven) {
		return false;
	}
	else {
		if(dragEven === false) {
			var nextDrag = config.container['drop_'+ (dropIndex+2)].dragname;
			if(typeof nextDrag !== 'undefined') {
				var nextDragIndex = nextDrag.split('_')[1];
				if(parseInt(nextDragIndex) !== parseInt(dragIndex) + 1) {
					return false;
				}
			}
		}
		else {
			var prevDrag = config.container['drop_'+ dropIndex].dragname;
			if(typeof prevDrag !== 'undefined') {
				var prevDragIndex = prevDrag.split('_')[1];
				if(parseInt(prevDragIndex) !== parseInt(dragIndex) - 1) {
					return false;
				}
			}
		}
		return true;
	}
}

function getClosetsDrops(container, prefix, drag) {
    var num = getChildrenNum(container, prefix);
    var drops = [];
    for (var i = 0; i < num; i++) {
        var name = prefix + (i + 1);
        var drop = container[name];
        var point1 = {x: drag.x, y: drag.y};
        var point2 = {x: drop.x, y: drop.y};
        drops.push([name, getDistance(point1, point2)]);
    }

    drops.sort(function(a, b) {
        return a[1] - b[1];
    });
    return drops;
}
function getGroupDrops(container, prefix, drag, groupid) {
    var drops = [];
    var group = getClosetsDrops(container, prefix, drag);
    var groupname = prefix + groupid;

    for (var id in group) {
        var dropname = group[id][0];
        var drop = container[dropname];
        if (groupname === prefix + drop.gname)
            drops.push(drop);
    }
    return drops;
}


/*Drag Dice*/
function setDragDice(config) {
    var exerciseContainer = config.container;
    exerciseContainer.id = config.id;

    var diceNamePrefix = 'dice';
    var dragNamePrefix = config.prefix;
    var dropNamePrefix = config.prefix2;

    var dropAlpha = 0;
    if (typeof (config.alpha) !== 'undefined')
        dropAlpha = config.alpha;

    var dropAlpha2 = 0.6;
    if (typeof (config.alpha2) !== 'undefined')
        dropAlpha2 = config.alpha2;

    var dropRange = 100;
    if (typeof (config.range) !== 'undefined')
        dropRange = config.range;

    var dropScale = 1.3;

    var playerMin = 2;
    if (typeof (config.players) !== 'undefined')
        playerMin = config.players.min;

    var playerMax = 2;
    if (typeof (config.players) !== 'undefined')
        playerMax = config.players.max;

    var gameResults = config.results;
    if (typeof (config.results.meta) === 'undefined')
        gameResults.meta = getChildrenNum(exerciseContainer, dropNamePrefix);
    if (typeof (config.results.shift) === 'undefined')
        gameResults.shift = 0;

    //Dodatkowe parametry zdefiniowane w pliku .fla
    if (typeof (config.exerciseAfterInit) === 'function') {
        config.exerciseAfterInit(exerciseContainer);
    }

    //Set dice
    exerciseContainer.currentPlayer = 0;
    if (typeof config.custom === 'undefined') {
        for (var diceName in exerciseContainer) {
            if (diceName.indexOf(diceNamePrefix) > -1) {
                var dice = exerciseContainer[diceName];
                dice.cursor = 'pointer';
                dice.name = diceName;
                dice.on('click', function() {
                    if(typeof config.exerciseExtraCurrentPlayer === 'function')
                        this.parent.currentPlayer = config.exerciseExtraCurrentPlayer();
                    else
                        this.parent.currentPlayer++;
                    
                    if (this.parent.currentPlayer > this.parent.playerNum)
                        this.parent.currentPlayer = 1;

                    for (var diceNextName in exerciseContainer) {
                        if (diceNextName.indexOf(diceNamePrefix) > -1) {
                            var diceNext = exerciseContainer[diceNextName];
                            var diceNum = 'num' + diceNextName.replace('dice', '');
                            diceNext.parent[diceNum] = getRandomNum(1, 6);
                            diceNext.gotoAndPlay(1);
                        }
                    }

                    playSound('ssDice');

                    for (var playerName in exerciseContainer) {
                        if (playerName.indexOf(dragNamePrefix) > -1) {
                            var playerPawn = exerciseContainer[playerName];
                            if (playerPawn.player === this.parent.currentPlayer) {
                                playerPawn.cursor = 'pointer';

                                TweenMax.to(playerPawn, 0.3, {scaleX: playerPawn.orgsx, scaleY: playerPawn.orgsy});
                                //Przeun obiektu na gore.
                                exerciseContainer.addChildAt(playerPawn, exerciseContainer.getNumChildren() - 1);
                            }
                            else {
                                playerPawn.cursor = 'default';
                                TweenMax.to(playerPawn, 0.3, {scaleX: playerPawn.orgsx / dropScale, scaleY: playerPawn.orgsy / dropScale});
                            }
                        }
                    }
                });
            }
        }
    }

    moveOutAllElements(exerciseContainer, 'dice', {y: -100});

    //Set drops
    for (var dropName in exerciseContainer) {
        if (dropName.indexOf(dropNamePrefix) > -1) {
            var dropItem = exerciseContainer[dropName];
            dropItem.alpha = dropAlpha;
        }
    }

    //Set drags properties
    var playerIndex = 0;
    for (var dragName in exerciseContainer) {
        if (dragName.indexOf(dragNamePrefix) > -1) {
            playerIndex++;
            var drag = exerciseContainer[dragName];
            drag.name = dragName;
            drag.orgx = exerciseContainer[dragName].x;
            drag.orgy = exerciseContainer[dragName].y;
            drag.orgr = exerciseContainer[dragName].rotation;
            drag.orgsx = exerciseContainer[dragName].scaleX;
            drag.orgsy = exerciseContainer[dragName].scaleY;
            drag.player = playerIndex;
            drag.position = 0;
            drag.scaleX = drag.orgsx / dropScale;
            drag.scaleY = drag.orgsy / dropScale;

            drag.on('mousedown', function(e) {
                if (this.cursor === 'pointer') {
                    this.offset = {
                        x: this.x - e.stageX,
                        y: this.y - e.stageY
                    };

                    if (typeof (this.orgz) === 'undefined')
                        this.orgz = exerciseContainer.getChildIndex(this);

                    if (typeof (exerciseContainer[this.dropname]) !== 'undefined') {
                        exerciseContainer[this.dropname].isdrop = false;
                        exerciseContainer[this.dropname].correct = false;
                        delete exerciseContainer[this.dropname].dragname;
                        delete exerciseContainer[this.dropname].draggroup;
                    }

                    delete this.dropname;

                    //Przeun obiektu na gore.
                    exerciseContainer.addChildAt(this, exerciseContainer.getNumChildren() - 1);
                }
            });

            drag.on('pressmove', function(e) {
                if (this.cursor === 'pointer') {
                    this.x = e.stageX + this.offset.x;
                    this.y = e.stageY + this.offset.y;

                    for (var dropName in exerciseContainer) {
                        if (dropName.indexOf(dropNamePrefix) > -1) {
                            var dropItem = this.parent[dropName];
                            TweenMax.to(dropItem, 0.2, {alpha: dropAlpha});

                            if (dropItem && dragInRange(this, dropItem, dropRange)) {
                                TweenMax.to(dropItem, 0.2, {alpha: dropAlpha2});
                            }
                            else {
                                TweenMax.to(dropItem, 0.2, {alpha: dropAlpha});
                            }
                        }
                    }
                }
            });

            drag.on('pressup', function(e) {
                if (this.cursor === 'pointer') {
                    var isDropped = false;
                    var dropNum = getChildrenNum(exerciseContainer, dropNamePrefix);
                    var dropNames = getClosetsDrops(exerciseContainer, dropNamePrefix, this);

                    for (var j = 0; j < dropNum; j++) {
                        var dropName = dropNames[j][0];
                        var dropIndex = dropName.replace(dropNamePrefix, '');
                        var dropItem = exerciseContainer[dropName];

                        if (dropItem && dragInRange(this, dropItem, dropRange)) {
                            var nextPosition = this.position + gameResults.shift;
                            for (var diceName in exerciseContainer) {
                                if (diceName.indexOf(diceNamePrefix) > -1) {
                                    var diceNext = exerciseContainer[diceName];
                                    var diceNum = 'num' + diceName.replace('dice', '');
                                    nextPosition = nextPosition + diceNext.parent[diceNum];
                                }
                            }

                            if (typeof config.exerciseCustomPosition === 'function') {
                                nextPosition = config.exerciseCustomPosition(this);
                            }

                            //console.log(dropIndex, nextPosition);

                            if (parseInt(dropIndex) === nextPosition) {
                                this.dropname = dropName;
                                this.cursor = 'default';
                                this.position = nextPosition;
                                dropItem.isdrop = true;
                                isDropped = true;

                                TweenMax.to(this, 0.2, {
                                    x: dropItem.x,
                                    y: dropItem.y,
                                    scaleX: this.orgsx / dropScale,
                                    scaleY: this.orgsy / dropScale,
                                    ease: Back.easeOut,
                                    onComplete: function() {
                                        this.target.orgx = dropItem.x;
                                        this.target.orgy = dropItem.y;

                                        //Meta
                                        if (parseInt(this.target.position) === parseInt(gameResults.meta))
                                            exerciseOnComplete();
                                    }
                                });

                                if (typeof config.exerciseExtraCondition === 'function') {
                                    config.exerciseExtraCondition(this);
                                }
                                break;
                            }
                        }
                    }

                    if (isDropped === true) {
                        exerciseGoodAnswer();
                    }

                    if (isDropped === false) {
                        exerciseBadAnswer();
                        TweenMax.to(this, 0.3, {
                            x: this.orgx,
                            y: this.orgy,
                            scaleX: this.orgsx / dropScale,
                            scaleY: this.orgsy / dropScale,
                            ease: Back.easeOut
                        });
                        //Ustaw poczatkowa glebokosc
                        exerciseContainer.addChildAt(this, this.orgz);
                    }
                }
            });
        }
    }

    //Set player num
    exerciseContainer.playerNum = getPromptValue(config.alert, function(value) {
        if (parseInt(value).toString() === 'NaN' || value < playerMin || value > playerMax) {
            showMessage('Sprawdź czy wpisałeś prawidłową liczbę graczy!');
            return false;
        }
        else {
            var playerIndexInit = 0;
            for (var playerName in config.container) {
                if (playerName.indexOf(config.prefix) > -1) {
                    //console.log(playerName);
                    var playerPawn = config.container[playerName];
                    playerIndexInit++;
                    if (playerIndexInit <= value) {
                        playerPawn.cursor = 'pointer';
                        //TweenMax.to(playerPawn, 0.3, {x: playerPawn.orgx, y: playerPawn.orgy, ease:Back.easeOut});
                    }
                    else {
                        playerPawn.y = -100;
                    }
                }
            }
            return true;
        }
    });

    //Animacja kostki
    moveInAllElements(exerciseContainer, 'dice', 0, 'Back.easeOut');

    //Dodatkowa funkcjonalności zdefiniowane w pliku .fla
    if (typeof (config.exerciseBeforeFinish) === 'function') {
        config.exerciseBeforeFinish();
    }
}

/* Input */
function setInput(config) {
    var exerciseContainer = config.container;
    var inputNamePrefix = config.prefix;
    var inputNum = getChildrenNum(exerciseContainer, inputNamePrefix);

    for (var i = 0; i < inputNum; i++) {
        var inputName = config.prefix + (i + 1);
        var input = exerciseContainer[inputName];
        input.cursor = 'pointer';
        input.name = inputName;
        input.on('click', function() {
            setInputValue(config, this);
            exerciseCheck(exerciseContainer, inputNamePrefix, inputNum);
        });
    }


}
function setInputValue(config, input) {
    var inputAlert = config.alert;
    var inputIndex = input.name.replace(config.prefix, '') - 1;
    var inputValue = getPromptValue(inputAlert);

    if (inputValue !== null) {
        input.textField.text = inputValue;
        input.value = inputValue;
        input.correct = inputCheck(config, input, inputIndex);
    }
    else {
        input.textField.text = '';
    }
}
function inputCheck(config, current, index) {
    var results = config.results;
    //console.log(current);
    if (current.value === results[index]) {
        exerciseGoodAnswer();
        return true;
    }
    else {
        exerciseBadAnswer();
        return false;
    }
}

/* Memo */
function setMemo(config) {
    var exerciseContainer = config.container;
    var memoNamePrefix = config.prefix;
    var memoPlay = 0;

    moveOutAllElements(exerciseContainer, memoNamePrefix, {x: stage.canvas.width / 2, y: stage.canvas.height / 2});

    //Dodatkowe parametry zdefiniowane w pliku .fla
    if (typeof (config.exerciseAfterInit) === 'function') {
        config.exerciseAfterInit(exerciseContainer);
    }

    for (var memoName in exerciseContainer) {
        if (memoName.indexOf(memoNamePrefix) > -1) {
            var memoItem = exerciseContainer[memoName];
            memoItem.cursor = 'pointer';
            memoItem.name = memoName;
            //memoItem.orgx = exerciseContainer[memoName].x;
            //memoItem.orgy = exerciseContainer[memoName].y;
            memoItem.orgr = exerciseContainer[memoName].rotation;
            memoItem.orgsx = exerciseContainer[memoName].scaleX;
            memoItem.orgsy = exerciseContainer[memoName].scaleY;
            memoItem.selected = false;
            memoItem.back.alpha = 0;
            memoItem.on('click', function() {
                var memoCurrent = this;
                //Zaznacz jezeli niezaznaczony
                if (memoCurrent.selected === false || typeof (memoCurrent.selected) === 'undefined') {
                    memoPlay++;
                    if (memoPlay <= 2) {
                        memoCurrent.selected = true;
                        //this.correct = selectCheck(config, this);
                        TweenMax.to(memoCurrent, 0.2, {
                            scaleX: 0,
                            onComplete: function() {
                                memoCurrent.back.alpha = 1;
                                TweenMax.to(memoCurrent, 0.5, {scaleX: memoCurrent.orgsx, ease: Back.easeOut});

                                //exerciseCheck(exerciseContainer, memoNamePrefix);
                                for (var memoPairName in exerciseContainer) {
                                    if (memoPairName.indexOf(memoNamePrefix) > -1) {
                                        var memoPair = exerciseContainer[memoPairName];
                                        if (memoPair.name !== memoCurrent.name && memoPair.selected === true) {


                                            var sufix1 = memoCurrent.name.replace(memoNamePrefix, '').split('_');
                                            var sufix2 = memoPair.name.replace(memoNamePrefix, '').split('_');

                                            if (sufix1[0] === sufix2[0] && ((sufix1[1] === 'a' && sufix2[1] === 'b') || (sufix1[1] === 'b' && sufix2[1] === 'a'))) {
                                                memoCurrent.correct = true;
                                                memoCurrent.selected = false;

                                                memoPair.correct = true;
                                                memoPair.selected = false;

                                                TweenMax.to(memoCurrent, 0.5, {delay: 0.8, scaleX: 0, scaleY: 0, ease: Back.easeIn, onComplete: exerciseGoodAnswer});
                                                TweenMax.to(memoPair, 0.5, {delay: 0.8, scaleX: 0, scaleY: 0, ease: Back.easeIn, onComplete: function() {
                                                        memoPlay = 0;
                                                        exerciseCheck(exerciseContainer, memoNamePrefix);
                                                    }});


                                            }
                                            else {
                                                memoCurrent.correct = false;
                                                memoCurrent.selected = false;

                                                memoPair.correct = false;
                                                memoPair.selected = false;

                                                TweenMax.to(memoCurrent, 0.2, {delay: 1, scaleX: 0, onComplete: function() {
                                                        memoCurrent.back.alpha = 0;
                                                        TweenMax.to(memoCurrent, 0.5, {scaleX: memoCurrent.orgsx, ease: Back.easeOut});
                                                    }
                                                });


                                                TweenMax.to(memoPair, 0.2, {delay: 1, scaleX: 0, onComplete: function() {
                                                        memoPair.back.alpha = 0;
                                                        TweenMax.to(memoPair, 0.5, {scaleX: memoCurrent.orgsx, ease: Back.easeOut, onComplete: function() {
                                                                memoPlay = 0;
                                                                exerciseCheck(exerciseContainer, memoNamePrefix);
                                                            }});
                                                        exerciseBadAnswer();
                                                    }
                                                });
                                            }
                                            break;
                                        }
                                    }
                                }
                            }
                        });
                    }
                }
            });
        }
    }

    //Animacja memow
    moveInAllElements(exerciseContainer, memoNamePrefix, 1, 'Back.easeOut', function() {
        var memoNum = getChildrenNum(exerciseContainer, memoNamePrefix) / 2;
        var memoUsed = [];
        var d = 0;
        var t = 0.2;
        for (var memoName in exerciseContainer) {
            if (memoName.indexOf(memoNamePrefix) > -1 && memoName.indexOf('_a') > -1) {
                d++;
                var memoCurrent = exerciseContainer[memoName];
                var memoIndex = getRandomNum(1, memoNum);
                if (memoUsed.indexOf(memoIndex) > -1)
                    continue;
                else
                    memoUsed.push(memoIndex);

                var memoSwap = exerciseContainer[memoNamePrefix + memoIndex + '_b'];

                TweenMax.to(memoCurrent, 0.5, {delay: d * t, x: memoSwap.orgx, y: memoSwap.orgy, ease: Back.easeOut});
                TweenMax.to(memoSwap, 0.5, {delay: d * t, x: memoCurrent.orgx, y: memoCurrent.orgy, ease: Back.easeOut});
            }
        }
    });

    //Dodatkowa funkcjonalności zdefiniowane w pliku .fla
    if (typeof (config.exerciseBeforeFinish) === 'function') {
        config.exerciseBeforeFinish(exerciseContainer);
    }
}

/* Paint */
function setPaint(config) {
    var exerciseContainer = config.container;
    var filterNamePrefix = config.prefix;
    var filterGroups = config.groups;
    var paintBrush = exerciseContainer.brush;
    var paintNamePrefix = config.prefix2;
    var paintGroups = config.groupdrops;


    //Ukrycie wszystkich elementow na scenie
    hideAllElements(exerciseContainer, 'paint_');
    //moveOutAllElements(exerciseContainer, 'filter_', {x: 2000});

    //Set group names
    if (typeof (filterGroups) !== 'undefined') {
        setGroupName(exerciseContainer, filterGroups, filterNamePrefix);
    }

    //Set group names
    if (typeof (paintGroups) !== 'undefined') {
        setGroupName(exerciseContainer, paintGroups, paintNamePrefix);
    }

    //Dodatkowe parametry zdefiniowane w pliku .fla
    if (typeof (config.exerciseAfterInit) === 'function') {
        config.exerciseAfterInit(exerciseContainer);
    }

    paintBrush.orgx = paintBrush.x;
    paintBrush.orgy = paintBrush.y;
    paintBrush.filter.filters = null;


    //Set filters
    for (var filterName in exerciseContainer) {
        if (filterName.indexOf(filterNamePrefix) > -1) {
            var paintBottle = exerciseContainer[filterName];
            if (paintBottle) {
                paintBottle.cursor = 'pointer';
                paintBottle.name = filterName;
                paintBottle.filter.filters = [new createjs.ColorFilter(0, 0, 0, 1, paintBottle.filters[0].redOffset, paintBottle.filters[0].greenOffset, paintBottle.filters[0].blueOffset)];
                //console.log(paintBottle.filter.getBounds());
                paintBottle.filter.cache(0, 0, paintBottle.filter.getBounds().width, paintBottle.filter.getBounds().height);
                paintBottle.filter.updateCache();
                paintBottle.filters = null;
                paintBottle.updateCache();
                paintBottle.on('click', function() {
                    var paintBottle = this;
                    var paintFilter = this.filter.filters[0];
                    TweenMax.to(paintBrush, 0.5, {x: this.x, y: this.y, ease: Quad.easeOut, onComplete: function() {
                            paintBrush.name = paintBottle.name;
                            paintBrush.gname = paintBottle.gname;
                            paintBrush.filter.cache(0, 0, 100, 100);

                            TweenMax.to(paintBrush, 0.3, {y: paintBrush.y + 20, repeat: 1, yoyo: true});
                            TweenMax.to(paintBrush.filter, 0.5, {alpha: 0.8, easel: {colorFilter: {redOffset: paintFilter.redOffset, greenOffset: paintFilter.greenOffset, blueOffset: paintFilter.blueOffset}}});

                            playSound('ssBrush');
                        }});
                });
            }
        }
    }
    //Set paint areas
    for (var paintName in exerciseContainer) {
        if (paintName.indexOf(paintNamePrefix) > -1) {
            var paintArea = exerciseContainer[paintName];
            if (paintArea) {
                paintArea.cursor = 'pointer';
                paintArea.name = paintName;
                paintArea.dropcolor = '';
                paintArea.filter.orgr = paintArea.filter.rotation;
                paintArea.filter.orgsx = paintArea.filter.scaleX;
                paintArea.filter.orgsy = paintArea.filter.scaleY;
                paintArea.filter.mask.orgr = paintArea.filter.mask.rotation;
                paintArea.filter.mask.orgsx = paintArea.filter.mask.scaleX;
                paintArea.filter.mask.orgsy = paintArea.filter.mask.scaleY;

                paintArea.filter.cache(paintArea.filter.getBounds().x, paintArea.filter.getBounds().y, paintArea.filter.getBounds().width, paintArea.filter.getBounds().height);
                var printMask = paintArea.filter.mask;
                printMask.scaleX = 0;
                printMask.scaleY = 0;
                paintArea.on('click', function(e) {
                    if (paintBrush.filter.filters !== null) {
                        var paintArea = this;
                        paintArea.dropcolor = paintBrush.name;
                        var paintIndex = this.name.replace(paintNamePrefix, '') - 1;
                        var paintFilter = paintBrush.filter.filters[0];
                        var mouseX = e.stageX;
                        var mouseY = e.stageY;
                        //console.log(this.parent.num, this.gname);
                        TweenMax.to(paintBrush, 0.5, {x: mouseX, y: mouseY, ease: Quad.easeOut, onComplete: function() {
                                TweenMax.to(paintBrush, 0.3, {y: paintBrush.y + 20, repeat: 1, yoyo: true});
                                var color = new createjs.ColorFilter(0, 0, 0, 1, paintFilter.redOffset, paintFilter.greenOffset, paintFilter.blueOffset);
                                //var maskX = Math.floor(mouseX - paintArea.getBounds().width / 2 - paintArea.x);
                                //var maskY = Math.floor(mouseY - paintArea.getBounds().height / 2 - paintArea.y);
                                var maskX = Math.floor(mouseX - paintArea.x);
                                var maskY = Math.floor(mouseY - paintArea.y);

                                var paintClone = paintArea.filter.clone(true);
                                paintClone.filters = [color];
                                paintClone.cache(paintClone.getBounds().x, paintClone.getBounds().y, paintClone.getBounds().width, paintClone.getBounds().height);
                                paintClone.mask = paintArea.filter.mask.clone(true);
                                paintClone.mask.x = maskX;
                                paintClone.mask.y = maskY;
                                paintClone.mask.scaleX = 0;
                                paintClone.mask.scaleY = 0;
                                //printClone.updateCache();
                                paintArea.addChildAt(paintClone, paintArea.getChildIndex(paintArea.filter));
                                paintArea.correct = dropCheck(config, paintBrush, paintIndex);
                                TweenMax.to(paintClone.mask, 1.2, {alpha: 1, rotation: printMask.orgr, scaleX: printMask.orgsx * 2, scaleY: printMask.orgsy * 2, onComplete: function() {
                                        exerciseCheck(exerciseContainer, paintNamePrefix);
                                    }
                                });
                            }
                        });
                    }
                    else {
                        showMessage('Wybierz kolor z palety farb.');
                    }
                });
            }
        }
    }

    //Animacja pedzla
    //TweenMax.from(paintBrush, 1, {delay: 0.5, x: 0, y: 0, alpha: 0, rotation: -1080, scaleX: 2, scaleY: 2, ease: Quart.easeOut});

    //Animacja puszek
    //moveInAllElements(exerciseContainer, 'filter_', 1, 'Back.easeOut');

    //Pokazanie pozostalych elementow na scenie
    showAllElements(exerciseContainer, 'paint_', 1);


    //Dodatkowe funkcjonalności zdefiniowane w pliku .fla
    if (typeof (config.exerciseBeforeFinish) === 'function') {
        config.exerciseBeforeFinish(exerciseContainer);
    }
}

/* PaintDice */
function setPaintDice(config) {
    var exerciseContainer = config.container;
    var filterNamePrefix = config.prefix;
    var filterGroups = config.groups;
    var paintBrush = exerciseContainer.brush;
    var paintNamePrefix = config.prefix2;
    var paintGroups = config.groupdrops;

    //Set group names
    if (typeof (filterGroups) !== 'undefined') {
        setGroupName(exerciseContainer, filterGroups, filterNamePrefix);
    }

    //Set group names
    if (typeof (paintGroups) !== 'undefined') {
        setGroupName(exerciseContainer, paintGroups, paintNamePrefix);
    }

    //Dodatkowe parametry zdefiniowane w pliku .fla
    if (typeof (config.exerciseAfterInit) === 'function') {
        config.exerciseAfterInit(exerciseContainer);
    }

    //Set brush
    paintBrush.orgx = paintBrush.x;
    paintBrush.orgy = paintBrush.y;
    paintBrush.filter.filters = null;


    //Set dice
    var dice = exerciseContainer['dice'];
    dice.cursor = 'pointer';
    dice.on('click', function() {
        this.parent.num = getRandomNum(1, 6);
        this.gotoAndPlay(1);
        playSound('ssDice');

        TweenMax.to(paintBrush, 0.5, {x: paintBrush.orgx, y: paintBrush.orgy, ease: Quad.easeOut});
        paintBrush.filter.filters = [new createjs.ColorFilter(0, 0, 0, 0, 0, 0, 0)];
        paintBrush.filter.cache(0, 0, 100, 100);
        paintBrush.filter.updateCache();
        paintBrush.filter.filters = null;

    });

    var conditionShift = 0;
    if (typeof (config.shift) !== 'undefined') {
        conditionShift = config.shift;
    }

    moveOutAllElements(exerciseContainer, 'dice', {y: -100});

    //Set filters
    for (var filterName in exerciseContainer) {
        if (filterName.indexOf(filterNamePrefix) > -1) {
            var paintBottle = exerciseContainer[filterName];
            paintBottle.cursor = 'pointer';
            paintBottle.name = filterName;
            paintBottle.filter.filters = [new createjs.ColorFilter(0, 0, 0, 1, paintBottle.filters[0].redOffset, paintBottle.filters[0].greenOffset, paintBottle.filters[0].blueOffset)];
            paintBottle.filter.cache(0, 0, paintBottle.filter.getBounds().width, paintBottle.filter.getBounds().height);
            paintBottle.filter.updateCache();
            paintBottle.filters = null;
            paintBottle.updateCache();
            paintBottle.on('click', function() {
                if (typeof this.parent.num !== 'undefined') {
                    if (parseInt(this.parent.num) === parseInt(this.gname)) {
                        var paintBottle = this;
                        var paintFilter = this.filter.filters[0];
                        TweenMax.to(paintBrush, 0.5, {x: this.x, y: this.y, ease: Quad.easeOut, onComplete: function() {
                                paintBrush.name = paintBottle.name;
                                paintBrush.gname = paintBottle.gname;
                                paintBrush.filter.cache(0, 0, 100, 100);

                                TweenMax.to(paintBrush, 0.3, {y: paintBrush.y + 20, repeat: 1, yoyo: true});
                                TweenMax.to(paintBrush.filter, 0.5, {alpha: 0.8, easel: {colorFilter: {redOffset: paintFilter.redOffset, greenOffset: paintFilter.greenOffset, blueOffset: paintFilter.blueOffset}}});

                                playSound('ssBrush');
                            }});
                    }
                    else {
                        showMessage('Nie możesz pobrać tego koloru!');
                    }
                }
                else {
                    showMessage('Najpierw rzuć kostką!');
                }
            });
        }
    }

    //Set paint areas
    for (var paintName in exerciseContainer) {
        if (paintName.indexOf(paintNamePrefix) > -1) {
            var paintArea = exerciseContainer[paintName];
            paintArea.cursor = 'pointer';
            paintArea.name = paintName;
            paintArea.dropcolor = '';
            paintArea.filter.orgr = paintArea.filter.rotation;
            paintArea.filter.orgsx = paintArea.filter.scaleX;
            paintArea.filter.orgsy = paintArea.filter.scaleY;
            paintArea.filter.mask.orgr = paintArea.filter.mask.rotation;
            paintArea.filter.mask.orgsx = paintArea.filter.mask.scaleX;
            paintArea.filter.mask.orgsy = paintArea.filter.mask.scaleY;

            paintArea.filter.cache(paintArea.filter.getBounds().x, paintArea.filter.getBounds().y, paintArea.filter.getBounds().width, paintArea.filter.getBounds().height);
            var printMask = paintArea.filter.mask;
            printMask.scaleX = 0;
            printMask.scaleY = 0;
            paintArea.on('click', function(e) {
                if (typeof this.parent.num !== 'undefined') {
                    if (paintBrush.filter.filters !== null) {
                        if (parseInt(this.parent.num) === parseInt(this.gname)) {
                            var paintArea = this;
                            paintArea.dropcolor = paintBrush.name;
                            var paintIndex = this.name.replace(paintNamePrefix, '') - 1;
                            var paintFilter = paintBrush.filter.filters[0];
                            var mouseX = e.stageX;
                            var mouseY = e.stageY;
                            TweenMax.to(paintBrush, 0.5, {x: mouseX, y: mouseY, ease: Quad.easeOut, onComplete: function() {
                                    TweenMax.to(paintBrush, 0.3, {y: paintBrush.y + 20, repeat: 1, yoyo: true});
                                    var color = new createjs.ColorFilter(0, 0, 0, 1, paintFilter.redOffset, paintFilter.greenOffset, paintFilter.blueOffset);
                                    //var maskX = Math.floor(mouseX - paintArea.getBounds().width / 2 - paintArea.x);
                                    //var maskY = Math.floor(mouseY - paintArea.getBounds().height / 2 - paintArea.y);
                                    var maskX = Math.floor(mouseX - paintArea.x);
                                    var maskY = Math.floor(mouseY - paintArea.y);

                                    var paintClone = paintArea.filter.clone(true);
                                    paintClone.filters = [color];
                                    paintClone.cache(paintClone.getBounds().x, paintClone.getBounds().y, paintClone.getBounds().width, paintClone.getBounds().height);
                                    paintClone.mask = paintArea.filter.mask.clone(true);
                                    paintClone.mask.x = maskX;
                                    paintClone.mask.y = maskY;
                                    paintClone.mask.scaleX = 0;
                                    paintClone.mask.scaleY = 0;
                                    //printClone.updateCache();
                                    paintArea.addChildAt(paintClone, paintArea.getChildIndex(paintArea.filter));
                                    paintArea.correct = dropCheck(config, paintBrush, paintIndex);
                                    TweenMax.to(paintClone.mask, 1.2, {alpha: 1, rotation: printMask.orgr, scaleX: printMask.orgsx * 2, scaleY: printMask.orgsy * 2, onComplete: function() {
                                            exerciseCheck(exerciseContainer, paintNamePrefix);
                                        }});
                                }
                            });
                        }
                        else {
                            showMessage('Nie możesz pomalować tego elementu! Wybierz inny');
                        }
                    }
                    else {
                        showMessage('Wybierz kolor z palety farb!');
                    }
                }
                else {
                    showMessage('Najpierw rzuć kostką!');
                }
            });
        }
    }

    //Animacja pedzla
    TweenMax.from(paintBrush, 1, {delay: 0.5, x: 0, y: 0, alpha: 0, rotation: -1080, scaleX: 2, scaleY: 2, ease: Quart.easeOut});

    //Animacja kostki
    moveInAllElements(exerciseContainer, 'dice', 1, 'Back.easeOut');

    //Dodatkowe funkcjonalności zdefiniowane w pliku .fla
    if (typeof (config.exerciseBeforeFinish) === 'function') {
        config.exerciseBeforeFinish(exerciseContainer);
    }
}
/* PaintDice2 */
function setPaintDice2(config) {
    var exerciseContainer = config.container;
    var filterNamePrefix = config.prefix;
    var filterGroups = config.groups;
    var paintBrush = exerciseContainer.brush;
    var paintNamePrefix = config.prefix2;
    var paintGroups = config.groupdrops;

    var playerMin = 2;
    if (typeof (config.players) !== 'undefined')
        playerMin = config.players.min;

    var playerMax = 2;
    if (typeof (config.players) !== 'undefined')
        playerMax = config.players.max;

    var playerNum = getPromptValue(config.alert, function(value) {
        if (parseInt(value).toString() === 'NaN' || value < playerMin || value > playerMax) {
            alert('Sprawdź czy wpisałeś prawidłową liczbę graczy!');
            return false;
        }
        return true;
    });

    //Set group names
    if (typeof (filterGroups) !== 'undefined') {
        setGroupName(exerciseContainer, filterGroups, filterNamePrefix);
    }

    //Set group names
    if (typeof (paintGroups) !== 'undefined') {
        setGroupName(exerciseContainer, paintGroups, paintNamePrefix);
    }

    //Dodatkowe parametry zdefiniowane w pliku .fla
    if (typeof (config.exerciseAfterInit) === 'function') {
        config.exerciseAfterInit(exerciseContainer);
    }

    //Set brush
    paintBrush.orgx = paintBrush.x;
    paintBrush.orgy = paintBrush.y;
    paintBrush.filter.filters = null;


    //Set dice
    var currentPlayer = 0;
    var dice = exerciseContainer['dice'];
    dice.cursor = 'pointer';
    dice.on('click', function() {
        this.parent.num = getRandomNum(1, 6);
        this.gotoAndPlay(1);
        playSound('ssDice');

        currentPlayer++;
        if (currentPlayer > playerNum)
            currentPlayer = 1;
        for (var playerName in exerciseContainer) {
            if (playerName.indexOf(filterNamePrefix) > -1) {
                var playerColor = exerciseContainer[playerName];
                if (playerColor.player === currentPlayer) {
                    playerColor.cursor = 'pointer';
                    TweenMax.to(playerColor, 0.3, {alpha: 1});
                }
                else {
                    playerColor.cursor = 'default';
                    TweenMax.to(playerColor, 0.3, {alpha: 0.5});
                }
            }
        }

        TweenMax.to(paintBrush, 0.5, {x: paintBrush.orgx, y: paintBrush.orgy, ease: Quad.easeOut});
        paintBrush.filter.filters = [new createjs.ColorFilter(0, 0, 0, 0, 0, 0, 0)];
        paintBrush.filter.cache(0, 0, 100, 100);
        paintBrush.filter.updateCache();
        paintBrush.filter.filters = null;

    });

    moveOutAllElements(exerciseContainer, 'dice', {y: -100});

    var playerIndex = 0;

    //Set filters
    for (var filterName in exerciseContainer) {
        if (filterName.indexOf(filterNamePrefix) > -1) {
            var paintBottle = exerciseContainer[filterName];
            playerIndex++;
            if (playerIndex <= playerNum) {
                //paintBottle.cursor = 'pointer';
                paintBottle.alpha = 0.5;
                paintBottle.name = filterName;
                paintBottle.filter.filters = [new createjs.ColorFilter(0, 0, 0, 1, paintBottle.filters[0].redOffset, paintBottle.filters[0].greenOffset, paintBottle.filters[0].blueOffset)];
                paintBottle.filter.cache(0, 0, paintBottle.filter.getBounds().width, paintBottle.filter.getBounds().height);
                paintBottle.filter.updateCache();
                paintBottle.filters = null;
                paintBottle.player = playerIndex;
                paintBottle.updateCache();
                paintBottle.on('click', function() {
                    if (typeof this.parent.num !== 'undefined') {
                        if (parseInt(this.player) === parseInt(currentPlayer)) {
                            var paintBottle = this;
                            var paintFilter = this.filter.filters[0];
                            TweenMax.to(paintBrush, 0.5, {x: this.x, y: this.y, ease: Quad.easeOut, onComplete: function() {
                                    paintBrush.name = paintBottle.name;
                                    paintBrush.gname = paintBottle.gname;
                                    paintBrush.filter.cache(0, 0, 100, 100);

                                    TweenMax.to(paintBrush, 0.3, {y: paintBrush.y + 20, repeat: 1, yoyo: true});
                                    TweenMax.to(paintBrush.filter, 0.5, {alpha: 0.8, easel: {colorFilter: {redOffset: paintFilter.redOffset, greenOffset: paintFilter.greenOffset, blueOffset: paintFilter.blueOffset}}});

                                    playSound('ssBrush');
                                }});
                        }
                    }
                    else {
                        showMessage('Najpierw rzuć kostką!');
                    }
                });
            }
            else {
                if (playerMax > 1) {
                    paintBottle.y = -100;
                }
            }
        }
    }

    //Set paint areas
    for (var paintName in exerciseContainer) {
        if (paintName.indexOf(paintNamePrefix) > -1) {
            var paintArea = exerciseContainer[paintName];
            paintArea.cursor = 'pointer';
            paintArea.name = paintName;
            paintArea.dropcolor = '';
            paintArea.player = '';
            paintArea.filter.orgr = paintArea.filter.rotation;
            paintArea.filter.orgsx = paintArea.filter.scaleX;
            paintArea.filter.orgsy = paintArea.filter.scaleY;
            paintArea.filter.mask.orgr = paintArea.filter.mask.rotation;
            paintArea.filter.mask.orgsx = paintArea.filter.mask.scaleX;
            paintArea.filter.mask.orgsy = paintArea.filter.mask.scaleY;

            paintArea.filter.cache(paintArea.filter.getBounds().x, paintArea.filter.getBounds().y, paintArea.filter.getBounds().width, paintArea.filter.getBounds().height);
            var printMask = paintArea.filter.mask;
            printMask.scaleX = 0;
            printMask.scaleY = 0;
            paintArea.on('click', function(e) {
                if (typeof this.parent.num !== 'undefined') {
                    if (paintBrush.filter.filters !== null) {
                        if (parseInt(this.parent.num) === parseInt(this.gname)) {
                            if (this.dropcolor === '') {
                                var paintArea = this;
                                paintArea.dropcolor = paintBrush.name;
                                paintArea.player = currentPlayer;
                                var paintIndex = this.name.replace(paintNamePrefix, '') - 1;
                                var paintFilter = paintBrush.filter.filters[0];
                                var mouseX = e.stageX;
                                var mouseY = e.stageY;
                                TweenMax.to(paintBrush, 0.5, {x: mouseX, y: mouseY, ease: Quad.easeOut, onComplete: function() {
                                        TweenMax.to(paintBrush, 0.3, {y: paintBrush.y + 20, repeat: 1, yoyo: true});
                                        var color = new createjs.ColorFilter(0, 0, 0, 1, paintFilter.redOffset, paintFilter.greenOffset, paintFilter.blueOffset);
                                        //var maskX = Math.floor(mouseX - paintArea.getBounds().width / 2 - paintArea.x);
                                        //var maskY = Math.floor(mouseY - paintArea.getBounds().height / 2 - paintArea.y);
                                        var maskX = Math.floor(mouseX - paintArea.x);
                                        var maskY = Math.floor(mouseY - paintArea.y);

                                        var paintClone = paintArea.filter.clone(true);
                                        paintClone.filters = [color];
                                        paintClone.cache(paintClone.getBounds().x, paintClone.getBounds().y, paintClone.getBounds().width, paintClone.getBounds().height);
                                        paintClone.mask = paintArea.filter.mask.clone(true);
                                        paintClone.mask.x = maskX;
                                        paintClone.mask.y = maskY;
                                        paintClone.mask.scaleX = 0;
                                        paintClone.mask.scaleY = 0;
                                        //printClone.updateCache();
                                        paintArea.addChildAt(paintClone, paintArea.getChildIndex(paintArea.filter));
                                        paintArea.correct = dropCheck(config, paintBrush, paintIndex);
                                        TweenMax.to(paintClone.mask, 1.2, {alpha: 1, rotation: printMask.orgr, scaleX: printMask.orgsx * 2, scaleY: printMask.orgsy * 2, onComplete: function() {
                                                exerciseCheck(exerciseContainer, paintNamePrefix, function() {
                                                    var bestPlayer = {};
                                                    for (var name in exerciseContainer) {
                                                        if (name.indexOf(paintNamePrefix) > -1) {
                                                            var paintItem = exerciseContainer[name];
                                                            if (paintItem.player !== '') {
                                                                if (!bestPlayer.hasOwnProperty(paintItem.player)) {
                                                                    if (typeof bestPlayer[paintItem.player] === 'undefined')
                                                                        bestPlayer[paintItem.player] = 0;
                                                                }
                                                                bestPlayer[paintItem.player]++;
                                                            }
                                                        }
                                                    }

                                                    var showResults = 'WYNIKI:\n';
                                                    for (var j in bestPlayer) {
                                                        showResults += 'Gracz ' + j + ': ' + bestPlayer[j] + '\n';
                                                    }

                                                    alert(showResults);
                                                });
                                            }});
                                    }
                                });
                            }
                            else {
                                showMessage('Ten element został już pomalowany! Wybierz inny.');
                            }
                        }
                        else {
                            showMessage('Nie możesz pomaleować tego elementu! Wybierz inny');
                        }
                    }
                    else {
                        showMessage('Wybierz kolor z palety farb!');
                    }
                }
                else {
                    showMessage('Najpierw rzuć kostką!');
                }
            });
        }
    }

    //Animacja pedzla
    TweenMax.from(paintBrush, 1, {delay: 0.5, x: 0, y: 0, alpha: 0, rotation: -1080, scaleX: 2, scaleY: 2, ease: Quart.easeOut});

    //Animacja kostki
    moveInAllElements(exerciseContainer, 'dice', 1, 'Back.easeOut');

    //Dodatkowe funkcjonalności zdefiniowane w pliku .fla
    if (typeof (config.exerciseBeforeFinish) === 'function') {
        config.exerciseBeforeFinish(exerciseContainer);
    }
}

/* Rope */
function setRope(config) {
    var exerciseContainer = config.container;
    var dragGroups = config.groups = config.groupdrags;
    var dragNamePrefix = config.prefix;

    var dropGroups = config.groupdrops;
    var dropNamePrefix = config.prefix2;

    var ropePointPrefix = config.prefix3;
    var ropeLinePrefix = config.prefix4;
    var ropeColor = config.color;
    var ropeStroke = config.stroke;

    var dragDropResults = config.results;
    var dragDropRange = 100;
    var dragDropAlpha = 0;
    var dragDropAlpha2 = 0.6;

    if (typeof (config.range) !== 'undefined')
        dragDropRange = config.range;

    if (typeof (config.alpha) !== 'undefined')
        dragDropAlpha = config.alpha;

    if (typeof (config.alpha2) !== 'undefined')
        dragDropAlpha2 = config.alpha2;

    //Dodatkowe parametry zdefiniowane w pliku .fla
    if (typeof (config.exerciseAfterInit) !== 'undefined' && typeof (config.exerciseAfterInit) === 'function') {
        config.exerciseAfterInit(exerciseContainer);
    }

    var dragNum = getChildrenNum(exerciseContainer, dragNamePrefix);
    var dropNum = getChildrenNum(exerciseContainer, dropNamePrefix);

    //Set group names
    if (typeof (dragGroups) !== 'undefined') {
        setGroupName(exerciseContainer, dragGroups, dragNamePrefix);
    }

    if (typeof (dropGroups) !== 'undefined') {
        setGroupName(exerciseContainer, dropGroups, dropNamePrefix);
    }

    //Set drops
    for (var h = 0; h < dropNum; h++) {
        var dropName = dropNamePrefix + (h + 1);
        var dropItem = exerciseContainer[dropName];
        dropItem.alpha = dragDropAlpha;
    }

    //Set drags properties
    for (var i = 0; i < dragNum; i++) {
        var ropePointName = ropePointPrefix + (i + 1);
        var ropePoint = exerciseContainer[ropePointName];

        var ropeLineName = ropeLinePrefix + (i + 1);
        stage[ropeLineName] = new createjs.Shape();
        stage[ropeLineName].name = ropeLineName;
        stage[ropeLineName].shadow = new createjs.Shadow("#fff", 0, 3, 5);
        exerciseContainer.addChild(stage[ropeLineName]);

        var dragName = dragNamePrefix + (i + 1);
        var drag = exerciseContainer[dragName];
        if (drag) {
            drag.cursor = 'pointer';
            drag.name = dragName;
            drag.orgx = exerciseContainer[dragName].x;
            drag.orgy = exerciseContainer[dragName].y;
            drag.on('mousedown', function(e) {
                this.parent.addChild(this); // Bump to top of zindex
                this.offset = {
                    x: this.x - e.stageX,
                    y: this.y - e.stageY
                };

                if (typeof (exerciseContainer[this.dropname]) !== 'undefined') {
                    exerciseContainer[this.dropname].isdrop = false;
                    exerciseContainer[this.dropname].correct = false;
                    delete exerciseContainer[this.dropname].dragname;
                    delete exerciseContainer[this.dropname].draggroup;
                }
                delete this.dropname;
                //playSound('ssDrag');
            });
            drag.on('pressmove', function(e) {
                var ropePointName = ropePointPrefix + this.name.replace(dragNamePrefix, '');
                var ropeLineName = ropeLinePrefix + this.name.replace(dragNamePrefix, '');
                var ropePoint = exerciseContainer[ropePointName];

                this.x = e.stageX + this.offset.x;
                this.y = e.stageY + this.offset.y;

                for (var j = 0; j < dropNum; j++) {
                    var dropName = dropNamePrefix + (j + 1);
                    var dropItem = this.parent[dropName];
                    TweenMax.to(dropItem, 0.2, {alpha: dragDropAlpha});

                    if (dropItem && dragInRange(this, dropItem, dragDropRange)) {
                        TweenMax.to(dropItem, 0.2, {alpha: dragDropAlpha2});
                    }
                    else {
                        TweenMax.to(dropItem, 0.2, {alpha: dragDropAlpha});
                    }
                }
                setRopeConnection(ropePoint, this, stage[ropeLineName], ropeColor, ropeStroke);
            });
            drag.on('pressup', function(e) {
                var isDropped = false;
                var dropNames = getClosetsDrops(exerciseContainer, dropNamePrefix, this);
                var dragItem = this;
                var ropePointName = ropePointPrefix + this.name.replace(dragNamePrefix, '');
                var ropeLineName = ropeLinePrefix + this.name.replace(dragNamePrefix, '');
                var ropePoint = exerciseContainer[ropePointName];

                for (var j = 0; j < dropNum; j++) {
                    var dropName = dropNames[j][0];
                    var dropIndex = dropName.replace(dropNamePrefix, '') - 1;
                    var dropItem = exerciseContainer[dropName];

                    if (dropItem && dragInRange(this, dropItem, dragDropRange) && dropItem.isdrop !== true) {
                        this.dropname = dropName;
                        isDropped = true;
                        dropItem.isdrop = true;
                        dropItem.dragname = this.name;
                        dropItem.draggroup = this.gname;
                        dropItem.correct = dropCheck(config, this, dropIndex);

                        TweenMax.to(this, 0.2, {
                            x: dropItem.x,
                            y: dropItem.y,
                            ease: Back.easeOut,
                            onComplete: function() {
                                exerciseCheck(exerciseContainer, dropNamePrefix, dropNum);
                                setRopeConnection(ropePoint, dragItem, stage[ropeLineName], ropeColor, ropeStroke);
                            }
                        });

                        TweenMax.to(dropItem, 0.2, {alpha: dragDropAlpha});

                        break;
                    }
                }


                if (isDropped === false) {
                    TweenMax.to(this, 0.3, {
                        x: this.orgx,
                        y: this.orgy,
                        ease: Back.easeOut,
                        onComplete: function() {
                            setRopeConnection(ropePoint, dragItem, stage[ropeLineName], ropeColor, ropeStroke);
                        }
                    });
                }

                var ropeIntervalLoop = 0;
                var ropeInterval = setInterval(function() {
                    setRopeConnection(ropePoint, dragItem, stage[ropeLineName], ropeColor, ropeStroke);

                    ropeIntervalLoop++;
                    if (ropeIntervalLoop === 100) {
                        clearInterval(ropeInterval);
                        dragItem.setChildIndex(stage.getNumChildren());
                    }
                }, 10);
            });
        }
    }

    //Dodatkowe funkcjonalności zdefiniowane w pliku .fla
    if (typeof (config.exerciseBeforeFinish) !== 'undefined' && typeof (config.exerciseBeforeFinish) === 'function') {
        config.exerciseBeforeFinish(exerciseContainer);
    }
}
function setRopeConnection(point1, point2, rope, color, stroke) {
    rope.graphics.clear().moveTo(point1.x, point1.y).setStrokeStyle(stroke, 'round').beginStroke(color);
    if (point1.y < point2.y)
        rope.graphics.bezierCurveTo(point1.x, point1.y, point1.x, point2.y, point2.x, point2.y).endStroke();
    else
        rope.graphics.bezierCurveTo(point1.x, point1.y, point2.x, point1.y, point2.x, point2.y).endStroke();
}

/* Selection */
function setSelect(config) {
    var exerciseContainer = config.container;
    var selectNamePrefix = config.prefix;
    var selectGroups = config.groups;
    var selectScale = 1.2;
    if (typeof (config.scale) !== 'undefined')
        selectScale = config.scale;

    hideAllElements(exerciseContainer, selectNamePrefix);

    //Dodatkowe parametry zdefiniowane w pliku .fla
    if (typeof (config.exerciseAfterInit) !== 'undefined' && typeof (config.exerciseAfterInit) === 'function') {
        config.exerciseAfterInit(exerciseContainer);
    }

    for (var selectName in exerciseContainer) {
        if (selectName.indexOf(selectNamePrefix) > -1) {
            var select = exerciseContainer[selectName];
            select.cursor = 'pointer';
            select.name = selectName;
            select.orgx = exerciseContainer[selectName].x;
            select.orgy = exerciseContainer[selectName].y;
            select.orgr = exerciseContainer[selectName].rotation;
            select.orgsx = exerciseContainer[selectName].scaleX;
            select.orgsy = exerciseContainer[selectName].scaleY;
            select.selected = false;
            select.correct = selectCheck(config, select, false);
            select['active'].alpha = 0;
            select.on('click', function() {
                this['active'].alpha = 0;
                //Zaznacz jezeli niezaznaczony
                if (this.selected === false || typeof (this.selected) === 'undefined') {
                    this.selected = true;
                    this.correct = selectCheck(config, this);
                    TweenMax.to(this, 0.8, {
                        rotation: 360,
                        scaleX: selectScale,
                        scaleY: selectScale,
                        ease: Back.easeOut,
                        onComplete: function() {
                            exerciseCheck(exerciseContainer, selectNamePrefix);
                        }
                    });
                    TweenMax.to(this['active'], 0.3, {alpha: 1});

                    //Odznacz pozostale w grupie
                    if (typeof (selectGroups !== 'undefined')) {
                        var selectId = this.name.replace(selectNamePrefix, '');
                        for (var j in selectGroups) {
                            //console.log(selectGroups[j].indexOf(selectIndex.toString()));
                            if (selectGroups[j].indexOf(selectId.toString()) > -1) {
                                for (var k in selectGroups[j]) {
                                    if (selectId.toString() !== selectGroups[j][k]) {
                                        var tmpSelectName = selectNamePrefix + selectGroups[j][k];
                                        var tmpSelect = exerciseContainer[tmpSelectName];
                                        if (tmpSelect.selected === true) {
                                            tmpSelect.selected = false;
                                            tmpSelect.correct = selectCheck(config, tmpSelect);
                                            TweenMax.to(tmpSelect, 0.6, {
                                                rotation: tmpSelect.orgr,
                                                scaleX: tmpSelect.orgsx,
                                                scaleY: tmpSelect.orgsy,
                                                ease: Back.easeOut,
                                            });
                                            TweenMax.to(tmpSelect['active'], 0.3, {alpha: 0});
                                        }
                                    }
                                }
                            }
                        }

                    }
                }
                //odznacz jezeli zaznaczony
                else {
                    this.selected = false;
                    this.correct = selectCheck(config, this);
                    TweenMax.to(this, 0.6, {
                        rotation: this.orgr,
                        scaleX: this.orgsx,
                        scaleY: this.orgsy,
                        ease: Back.easeOut,
                        onComplete: function() {
                            exerciseCheck(exerciseContainer, selectNamePrefix);
                        }
                    });
                    TweenMax.to(this['active'], 0.3, {alpha: 0});
                }
            });
        }
    }

    //Animacja selectow
    showAllElements(exerciseContainer, selectNamePrefix, 1);

    //Dodatkowa funkcjonalności zdefiniowane w pliku .fla
    if (typeof (config.exerciseBeforeFinish) !== 'undefined' && typeof (config.exerciseBeforeFinish) === 'function') {
        config.exerciseBeforeFinish(exerciseContainer);
    }
}
function selectCheck(config, current, showanswer) {
    var index = current.name.replace(config.prefix, '') - 1;
    var results = config.results;
    if ((current.selected === true && results[index] === '1') || (current.selected === false && results[index] === '0')) {
        if (showanswer !== false)
            exerciseGoodAnswer();
        return true;
    }
    else {
        if (showanswer !== false)
            exerciseBadAnswer();
        return false;
    }
}

/* Sortable */
function setSortable(config, sortAxis) {
    var exerciseContainer = config.container;
    var sortNamePrefix = config.prefix;
    var sortNum = getChildrenNum(exerciseContainer, sortNamePrefix);
    var sortResults = config.results;

    for (var i = 0; i < sortNum; i++) {
        var sortName = sortNamePrefix + (i + 1);
        var sortBox = exerciseContainer[sortName];

        if (sortBox) {
            sortBox.name = sortName;
            sortBox.order = i + 1;
            sortBox.orgx = exerciseContainer[sortName].x;
            sortBox.orgy = exerciseContainer[sortName].y;
            sortBox.cursor = 'pointer';
            sortBox.correct = sortCheck(config, sortBox, false);
            //Event mousedown
            sortBox.on('mousedown', function(e) {
                this.parent.addChild(this);
                this.offset = {
                    x: this.x - e.stageX,
                    y: this.y - e.stageY
                };
            });
            //Event move
            sortBox.on('pressmove', function(e) {
                this.x = e.stageX + this.offset.x;
                //this.y = e.stageY + this.offset.y;
                switch (sortAxis) {
                    case 'x':
                        sortIsOverAxisX(config, this);
                        break;
                    case 'y':
                        sortIsOverAxisY(exerciseContainer, sortNamePrefix, sortNum, this, 100);
                        break;
                    default:
                        sortIsOverAxisX(config, this);
                        break;
                }

            });
            //Event mouseup
            sortBox.on('pressup', function(e) {
                this.correct = sortCheck(config, this);
                TweenMax.to(this, 0.3, {
                    x: this.orgx,
                    y: this.orgy,
                    ease: Back.easeOut,
                    onComplete: function() {
                        exerciseCheck(exerciseContainer, sortNamePrefix, sortNum);
                    }
                });
            });
        }
    }
}
function sortIsOverAxisX(config, sortCurrent) {
    var exerciseContainer = config.container;
    var sortNamePrefix = config.prefix;
    var sortNum = getChildrenNum(exerciseContainer, sortNamePrefix);
    var sortRange = 100;

    if (typeof (config.range) !== 'undefined')
        sortRange = config.range;

    for (var i = 0; i < sortNum; i++) {
        var sortBox = exerciseContainer[sortNamePrefix + (i + 1)];
        if (sortCurrent.x > sortBox.x - sortRange / 2 &&
                sortCurrent.x < sortBox.x + sortRange / 2 &&
                (sortCurrent.y > sortBox.y - sortRange / 2 && sortCurrent.y < sortBox.y + sortRange / 2) &&
                sortCurrent.name !== sortBox.name) {
            var tmpx = sortCurrent.orgx;
            var tmpy = sortCurrent.orgy;
            var tmpo = sortCurrent.order;
            sortCurrent.orgx = sortBox.orgx;
            sortCurrent.orgy = sortBox.orgy;
            sortCurrent.order = sortBox.order;
            sortBox.x = sortBox.orgx = tmpx;
            sortBox.y = sortBox.orgy = tmpy;
            sortBox.order = tmpo;
            sortBox.correct = sortCheck(config, sortBox, false);
        }
    }
}
function sortIsOverAxisY(sortContainer, sortNamePrefix, sortNum, sortCurrent, sortRange) {
    //var sortNum = sortGroup.length;
    for (var i = 0; i < sortNum; i++) {
        var sortBox = sortContainer[sortNamePrefix + (i + 1)];
        if (sortCurrent.y > sortBox.y - sortRange / 2 &&
                sortCurrent.y < sortBox.y + sortRange / 2 &&
                sortCurrent.name !== sortBox.name) {
            var tmpx = sortCurrent.orgx;
            var tmpy = sortCurrent.orgy;
            sortCurrent.orgx = sortBox.orgx;
            sortCurrent.orgy = sortBox.orgy;
            sortBox.x = sortBox.orgx = tmpx;
            sortBox.y = sortBox.orgy = tmpy;
        }
    }
}
function sortCheck(config, current, showanswer) {
    var sortPrefix = config.prefix;
    var sortResults = config.results;
    var sortId = current.name.replace(sortPrefix, '');
    var sortIndex = current.order - 1;

    if (sortId === sortResults[sortIndex]) {
        if (showanswer !== false)
            exerciseGoodAnswer();
        return true;
    }
    else {
        if (showanswer !== false)
            exerciseBadAnswer();
        return false;
    }
}


function setSounds(config, prefix, animation) {
    var exerciseId = config.id;
    var exerciseContainer = config.container;

    var queue = new createjs.LoadQueue();
    queue.installPlugin(createjs.Sound);
    createjs.Sound.alternateExtensions = ["ogg"];

    var soundPrefix = 'sound_';
    if (typeof prefix !== 'undefined')
        soundPrefix = prefix;

    for (var soundName in exerciseContainer) {
        if (soundName.indexOf(soundPrefix) > -1) {
            //console.log(soundName);
            var sound = exerciseContainer[soundName];
            var soundId = exerciseId + '_' + soundName.replace(soundPrefix, '');
            var soundSrc = getAssetDir() + '/sounds/' + soundId + '.mp3';
            queue.loadFile({id: soundId, src: soundSrc});
            sound.cursor = 'pointer';
            sound.name = soundName;
            sound.on('mousedown', function() {
                var sound = this;

                if (animation !== false) {
                    TweenMax.to(sound, 0.5, {rotation: 360, ease: Back.easeOut, onComplete: function() {
                            sound.rotation = 0;
                        }});
                }

                //console.log(exerciseId + '_' + sound.name.replace(soundPrefix, ''));
                createjs.Sound.play(exerciseId + '_' + sound.name.replace(soundPrefix, ''));
            });
        }
    }
}