<commit_before>var Item = function(sprite, x, y, width, verticalBuffer) {
    // The image/sprite for our enemies, this uses
    // a helper we've provided to easily load images
    this.sprite = sprite;
    this.startingXPosition = x;
    this.startingYPosition = y;
    this.x = x; // Item's current x-position
    this.y = y; // Item's current y-position
    this.halfVisibleWidth = width / 2;
    this.rowAdjust = verticalBuffer;
};

Item.prototype.midPoint = function() {
    return this.x + 50.5;
};

Item.prototype.visibleLeft = function() {
    return this.midPoint() - this.halfVisibleWidth;
};

Item.prototype.visibleRight = function() {
    return this.midPoint() + this.halfVisibleWidth;
};

Item.prototype.onRow = function() {
    return (this.y - this.rowAdjust)/83;
};

Item.prototype.onColumn = function() {
    return(this.x / 101);
};

Item.prototype.render = function() {
    ctx.drawImage(Resources.get(this.sprite), this.x, this.y);
};

Item.prototype.collidingWith = function(item) {
    if(this.onRow() == item.onRow()) {
        // the two items are on the same row; check to see if they are touching each other
        return (item.visibleLeft() < this.visibleRight() &&
            item.visibleLeft() > this.visibleLeft())
            ||
            (item.visibleRight() < this.visibleRight() &&
            item.visibleRight() > this.visibleLeft());
    }
};

Item.prototype.resetPosition = function() {
    this.x = this.startingXPosition;
    this.y = this.startingYPosition;
};

var Enemy = function() {
    this.verticalBuffer = 57;

    this.generateYPosition = function() {
        return Math.floor(Math.random() * 3) * 83 + this.verticalBuffer;
    };

    Item.call(this,
        'images/enemy-bug-red.png',
        -102,
        this.generateYPosition(),
        86,
        this.verticalBuffer);

    this.setSpeed();
};

Enemy.inheritsFrom(Item);

// Update the enemy's position, required method for game
// Parameter: dt, a time delta between ticks
Enemy.prototype.update = function(dt) {
    // if the enemy runs off the screen, reset the enemy so that it can
    // appear on the screen again
    if (this.x > canvas.width+102) {
        this.reset();
    }
    // any movement is multiplied by the dt parameter to ensure the game
    // runs at the same speed for all computers.
    this.x += this.speed * dt;
};

Enemy.prototype.reset = function() {
    this.resetPosition();
    this.setSpeed();
};

/**
 * Sets the speed of the enemy to a random value between 100 and 599 and
 * then sets the enemy sprite based on the speed range
 */
Enemy.prototype.setSpeed = function () {
    this.speed= Math.floor((Math.random() * 500) + 100);
    this.setSpriteBySpeed();
};

/**
 * Sets the sprite image based on the speed of the enemy
 *
 * Slowest (100-199) - blue
 * Slower  (200-299) - purple
 * Normal  (300-399) - red
 * Faster  (400-499) - yellow
 * Fastest (500-599) - green
 */
Enemy.prototype.setSpriteBySpeed = function () {
    if(this.speed >= 500) {
        this.sprite = 'images/enemy-bug-green.png';
    } else if (this.speed >= 400) {
        this.sprite = 'images/enemy-bug-yellow.png';
    } else if (this.speed >= 300) {
        this.sprite = 'images/enemy-bug-red.png';
    } else if (this.speed >= 200) {
        this.sprite = 'images/enemy-bug-purple.png';
    } else if (this.speed >= 100) {
        this.sprite = 'images/enemy-bug-blue.png';
    }
};

var Player = function() {
    Item.call(this, 'images/char-boy.png', 202, 380, 31, 48);
    this.verticalMove = 83;
    this.horizontalMove = 101;
    this.collideSound = new Audio('sounds/crunch.wav');
    this.splashSound = new Audio('sounds/water-splash.wav');
    this.resetWalkingArray();
};

Player.inheritsFrom(Item);

Player.prototype.update = function() {
    // as per the comment in engine.js; this method should focus purely
    // on updating the data/properties related to the object
    for(var enemy in allEnemies) {
        if(allEnemies[enemy].collidingWith(this)) {
            this.collideSound.play();
            //TODO: move this functionality into the GameProperties object; beef up that object
            if (GameProperties.currentGamePoints > GameProperties.bestGamePoints) {
                GameProperties.bestGamePoints = GameProperties.currentGamePoints;
                console.log('Assigning points: '+GameProperties.bestGamePoints.toString());
            }
            GameProperties.consecutiveSuccesses = 0;
            GameProperties.currentGamePoints = 0;
            this.reset();
            break;
        }
    }

    if (!pauseScreen.colouredTileModeOn) {
        this.resetWalkingArray();
    }

    if(this.walkedSuccess[0] && this.walkedSuccess[0].length == 5 &&
        this.walkedSuccess[1] && this.walkedSuccess[1].length == 5 &&
        this.walkedSuccess[2] && this.walkedSuccess[2].length == 5) {
        GameProperties.currentGamePoints += 100;
        player.resetWalkingArray();
    }
};

Player.prototype.reset = function() {
    this.resetWalkingArray();
    this.resetPosition();
};

Player.prototype.resetWalkingArray = function() {
    this.walkedSuccess = [];
    for(var i = 0; i < 3; i++) {
        this.walkedSuccess.push([]);
    }
};

Player.prototype.handleInput = function(input) {
    switch (input) {
        case 'left':
            this.moveLeft();
            break;
        case 'up':
            this.moveUp();
            break;
        case 'right':
            this.moveRight();
            break;
        case 'down':
            this.moveDown();
            break;
    }
    if(this.onRow() < 3) {
        if(this.walkedSuccess[this.onRow()].indexOf(this.onColumn()) == -1) {
            GameProperties.currentGamePoints += 10;
            this.walkedSuccess[this.onRow()].push(this.onColumn());
        }
    }
};

Player.prototype.moveLeft = function() {
    if(this.x >= this.horizontalMove) {
        this.x -= this.horizontalMove;
    }
};

Player.prototype.moveRight = function() {
    if(this.x + this.horizontalMove < canvas.width) {
        this.x += this.horizontalMove;
    }
};

Player.prototype.hasReachedTopRow = function() {
    return this.y <= this.verticalMove;
};

Player.prototype.moveUp = function() {

    if(this.hasReachedTopRow()) {
        this.splashSound.play();
        //TODO: should probably move the tile mode attribute to GameProperties
        //TODO: GameProperties.playerReachedTopRow()
        if(pauseScreen.colouredTileModeOn) {
            // lose 10 points for going in the water
            GameProperties.currentGamePoints -= 30;
        }
        else {
            GameProperties.consecutiveSuccesses++;
        }
        this.resetPosition();
    } else {
        this.y -= this.verticalMove;
    }
};

Player.prototype.moveDown = function() {
    if(this.y < this.startingYPosition) {
        this.y += this.verticalMove;
    }
};

Player.prototype.setCharacter = function(sprite) {
    this.sprite = sprite;
};

/**
 * Creates a new PauseScreen class.  This class contains all the information necessary to display the pause screen
 * with all game option information visible to the user.
 * @constructor
 */
var PauseScreen = function() {
    //TODO: consider passing this information into the class or putting it in GameProperties
    this.characterImages = [
        'images/char-boy.png',
        'images/char-cat-girl.png',
        'images/char-horn-girl.png',
        'images/char-pink-girl.png',
        'images/char-princess-girl.png'
    ];

    this.characterSelection = 0;
    this.colouredTileModeOn = false;
};

/**
 * This is called to draw the pause screen on the canvas.
 * The user is allowed to select a character and set which game modes they would like active.
 * There is also a message letting the user know how to exit the pause screen.
 */
PauseScreen.prototype.render = function() {
    this.renderOverlay();
    this.drawTitle("SELECT A CHARACTER", canvas.width/2, 100);
    this.drawCharacterSelect(21, 115, 90);
    this.drawTitle("GAME MODES", canvas.width/2, 330);
    this.drawGameModeText('images/1-icon.png', 'Coloured Tile', this.colouredTileModeOn, 337);
    this.drawGameModeText('images/2-icon.png', 'Collectibles', false, 397);
    this.drawGameModeText('images/3-icon.png', 'Alternate Directions', false, 457);
    this.drawEscapeMessage(555);
};

/**
 * This method draws the background and border of the pause screen so that the game options are more visible to
 * the user.
 */
PauseScreen.prototype.renderOverlay = function() {
    ctx.globalAlpha = 0.85;
    ctx.fillStyle = 'black';
    ctx.fillRect(10, 60, 485, 516);
    ctx.globalAlpha = 1;
    ctx.strokeStyle = 'white';
    ctx.lineWidth = 2;
    ctx.strokeRect(10, 60, 485, 516);
};

/**
 * Draw a grey centered title on the canvas with a black shadow.
 * @param {string} title - the text of the title
 * @param {number} x - the canvas x-coordinate of the middle of the title
 * @param {number} y - the canvas y-coordinate of the title text
 */
PauseScreen.prototype.drawTitle = function(title, x, y) {
    ctx.textAlign = "center";
    ctx.font = "26pt Nunito, sans-serif";
    ctx.fillStyle = 'black';
    // put a shadow behind the title text
    ctx.fillText(title, x+3, y+3);
    ctx.fillStyle = 'grey';
    ctx.fillText(title, x, y);
};

/**
 * Draw the characters available for selection.
 * @param {number} x - the canvas x-coordinate of the left-most character image
 * @param {number} y - the canvas x-coordinate of all the character images
 * @param {number} spacingInterval - the x-coordinate interval to use to evenly space the character images
 */
PauseScreen.prototype.drawCharacterSelect = function(x, y, spacingInterval) {
    ctx.drawImage(Resources.get('images/Selector.png'), this.characterSelection * spacingInterval + x, y);

    for(var characterIndex in this.characterImages) {
        ctx.drawImage(Resources.get(this.characterImages[characterIndex]), characterIndex * spacingInterval + x, y);
    }
};

/**
 * Draw the available game mode text as well as whether the game mode is currently "ON" or "OFF"
 * @param {string} image - the url of the image file
 * @param {string} modeText - the text describing the mode to the user
 * @param {boolean} isOn - true if this game mode is enabled; false if this game mode is disabled
 * @param y - the canvas y-coordinate of where this text should be placed on the canvas
 */
PauseScreen.prototype.drawGameModeText = function(image, modeText, isOn, y) {
    ctx.font = '20pt Nunito, sans-serif';
    ctx.textAlign = 'left';

    var gameModeText = modeText + ' - ';
    if(isOn) {
        // if the game mode is enabled then append ON and colour text green
        ctx.fillStyle = 'green';
        gameModeText += 'ON';
    }
    else {
        // if the game mode is disabled then append OFF and colour text red
        ctx.fillStyle = 'red';
        gameModeText += 'OFF';
    }

    ctx.drawImage(Resources.get(image), 30, y);
    ctx.fillText(gameModeText, 100, y+40);
};

/**
 * Draws the message that lets the user know to press the escape key to exit the pause screen.
 * @param {number} y - the canvas y-coordinate of where the message should be drawn
 */
PauseScreen.prototype.drawEscapeMessage = function(y) {
    ctx.fillStyle = 'white';
    ctx.font = '20pt Nunito, sans-serif';
    ctx.textAlign = 'center';
    ctx.fillText('Press      to play game', canvas.width/2, y);
    ctx.drawImage(Resources.get('images/esc-icon.png'), canvas.width/2 - 72, y-34);
};

/**
 * This function is called by the event listener that is listening for keyUp events when the game is
 * considered 'paused'.  Based on which key was pressed either a new character is selected or a game mode
 * is enabled/disabled.
 * @param {string} input - the string representation of the key that the user pressed
 */
PauseScreen.prototype.handleInput = function (input) {
    switch (input) {
        case 'left':
            if(this.characterSelection > 0) {
                this.characterSelection--;
            }
            break;
        case 'right':
            if(this.characterSelection < this.characterImages.length-1) {
                this.characterSelection++;
            }
            break;
        case 'one':
            //TODO: move this atribute to GameProperties
            this.colouredTileModeOn = !this.colouredTileModeOn;
            GameProperties.currentGamePoints = 0;
            player.resetWalkingArray();
            break;
    }
};

/**
 * Gets the URL of the image for the selected character
 * @returns {string} - image URL of the selected character
 */
PauseScreen.prototype.getSelectedCharacterImageURL = function() {
    return this.characterImages[this.characterSelection];
};

allEnemies = [new Enemy(), new Enemy(), new Enemy(), new Enemy(), new Enemy()];
player = new Player();
pauseScreen = new PauseScreen();

/**
 * This listens for key presses and sends the keys to the Player.handleInput() method.
 */
document.addEventListener('keyup', function(e) {
    var escapeKey = 27;
    //TODO: remove following log message
    console.log(e.keyCode.toString());
    var allowedKeys = {
        37: 'left',
        38: 'up',
        39: 'right',
        40: 'down',
        49: 'one'
    };

    if (e.keyCode == escapeKey) {
        GameProperties.pauseGame = !GameProperties.pauseGame;
    }

    if(GameProperties.pauseGame) {
        pauseScreen.handleInput(allowedKeys[e.keyCode]);
    }
    else {
        player.handleInput(allowedKeys[e.keyCode]);
    }
});
<commit_msg>Documented Item class constructor.<commit_after>/**
 * Base class that represents an item displayed on the screen that has a location and visible width and height
 *
 * @param {string} sprite - image file that is used to render on the canvas for this item
 * @param {number} x - x coordinate position on the canvas of this item
 * @param {number} y - y coordinate position on the canvas of this item
 * @param {number} width - the visible width of the object (used to determine collision with other objects)
 * @param {number} verticalBuffer - number of pixels from the top of the canvas
 * @constructor
 */
var Item = function(sprite, x, y, width, verticalBuffer) {
    // The image/sprite for our enemies, this uses
    // a helper we've provided to easily load images
    this.sprite = sprite;
    this.startingXPosition = x;
    this.startingYPosition = y;
    this.x = x; // Item's current x-position
    this.y = y; // Item's current y-position
    this.halfVisibleWidth = width / 2;
    this.rowAdjust = verticalBuffer;
};

Item.prototype.midPoint = function() {
    return this.x + 50.5;
};

Item.prototype.visibleLeft = function() {
    return this.midPoint() - this.halfVisibleWidth;
};

Item.prototype.visibleRight = function() {
    return this.midPoint() + this.halfVisibleWidth;
};

Item.prototype.onRow = function() {
    return (this.y - this.rowAdjust)/83;
};

Item.prototype.onColumn = function() {
    return(this.x / 101);
};

Item.prototype.render = function() {
    ctx.drawImage(Resources.get(this.sprite), this.x, this.y);
};

Item.prototype.collidingWith = function(item) {
    if(this.onRow() == item.onRow()) {
        // the two items are on the same row; check to see if they are touching each other
        return (item.visibleLeft() < this.visibleRight() &&
            item.visibleLeft() > this.visibleLeft())
            ||
            (item.visibleRight() < this.visibleRight() &&
            item.visibleRight() > this.visibleLeft());
    }
};

Item.prototype.resetPosition = function() {
    this.x = this.startingXPosition;
    this.y = this.startingYPosition;
};

var Enemy = function() {
    this.verticalBuffer = 57;

    this.generateYPosition = function() {
        return Math.floor(Math.random() * 3) * 83 + this.verticalBuffer;
    };

    Item.call(this,
        'images/enemy-bug-red.png',
        -102,
        this.generateYPosition(),
        86,
        this.verticalBuffer);

    this.setSpeed();
};

Enemy.inheritsFrom(Item);

// Update the enemy's position, required method for game
// Parameter: dt, a time delta between ticks
Enemy.prototype.update = function(dt) {
    // if the enemy runs off the screen, reset the enemy so that it can
    // appear on the screen again
    if (this.x > canvas.width+102) {
        this.reset();
    }
    // any movement is multiplied by the dt parameter to ensure the game
    // runs at the same speed for all computers.
    this.x += this.speed * dt;
};

Enemy.prototype.reset = function() {
    this.resetPosition();
    this.setSpeed();
};

/**
 * Sets the speed of the enemy to a random value between 100 and 599 and
 * then sets the enemy sprite based on the speed range
 */
Enemy.prototype.setSpeed = function () {
    this.speed= Math.floor((Math.random() * 500) + 100);
    this.setSpriteBySpeed();
};

/**
 * Sets the sprite image based on the speed of the enemy
 *
 * Slowest (100-199) - blue
 * Slower  (200-299) - purple
 * Normal  (300-399) - red
 * Faster  (400-499) - yellow
 * Fastest (500-599) - green
 */
Enemy.prototype.setSpriteBySpeed = function () {
    if(this.speed >= 500) {
        this.sprite = 'images/enemy-bug-green.png';
    } else if (this.speed >= 400) {
        this.sprite = 'images/enemy-bug-yellow.png';
    } else if (this.speed >= 300) {
        this.sprite = 'images/enemy-bug-red.png';
    } else if (this.speed >= 200) {
        this.sprite = 'images/enemy-bug-purple.png';
    } else if (this.speed >= 100) {
        this.sprite = 'images/enemy-bug-blue.png';
    }
};

var Player = function() {
    Item.call(this, 'images/char-boy.png', 202, 380, 31, 48);
    this.verticalMove = 83;
    this.horizontalMove = 101;
    this.collideSound = new Audio('sounds/crunch.wav');
    this.splashSound = new Audio('sounds/water-splash.wav');
    this.resetWalkingArray();
};

Player.inheritsFrom(Item);

Player.prototype.update = function() {
    // as per the comment in engine.js; this method should focus purely
    // on updating the data/properties related to the object
    for(var enemy in allEnemies) {
        if(allEnemies[enemy].collidingWith(this)) {
            this.collideSound.play();
            //TODO: move this functionality into the GameProperties object; beef up that object
            if (GameProperties.currentGamePoints > GameProperties.bestGamePoints) {
                GameProperties.bestGamePoints = GameProperties.currentGamePoints;
                console.log('Assigning points: '+GameProperties.bestGamePoints.toString());
            }
            GameProperties.consecutiveSuccesses = 0;
            GameProperties.currentGamePoints = 0;
            this.reset();
            break;
        }
    }

    if (!pauseScreen.colouredTileModeOn) {
        this.resetWalkingArray();
    }

    if(this.walkedSuccess[0] && this.walkedSuccess[0].length == 5 &&
        this.walkedSuccess[1] && this.walkedSuccess[1].length == 5 &&
        this.walkedSuccess[2] && this.walkedSuccess[2].length == 5) {
        GameProperties.currentGamePoints += 100;
        player.resetWalkingArray();
    }
};

Player.prototype.reset = function() {
    this.resetWalkingArray();
    this.resetPosition();
};

Player.prototype.resetWalkingArray = function() {
    this.walkedSuccess = [];
    for(var i = 0; i < 3; i++) {
        this.walkedSuccess.push([]);
    }
};

Player.prototype.handleInput = function(input) {
    switch (input) {
        case 'left':
            this.moveLeft();
            break;
        case 'up':
            this.moveUp();
            break;
        case 'right':
            this.moveRight();
            break;
        case 'down':
            this.moveDown();
            break;
    }
    if(this.onRow() < 3) {
        if(this.walkedSuccess[this.onRow()].indexOf(this.onColumn()) == -1) {
            GameProperties.currentGamePoints += 10;
            this.walkedSuccess[this.onRow()].push(this.onColumn());
        }
    }
};

Player.prototype.moveLeft = function() {
    if(this.x >= this.horizontalMove) {
        this.x -= this.horizontalMove;
    }
};

Player.prototype.moveRight = function() {
    if(this.x + this.horizontalMove < canvas.width) {
        this.x += this.horizontalMove;
    }
};

Player.prototype.hasReachedTopRow = function() {
    return this.y <= this.verticalMove;
};

Player.prototype.moveUp = function() {

    if(this.hasReachedTopRow()) {
        this.splashSound.play();
        //TODO: should probably move the tile mode attribute to GameProperties
        //TODO: GameProperties.playerReachedTopRow()
        if(pauseScreen.colouredTileModeOn) {
            // lose 10 points for going in the water
            GameProperties.currentGamePoints -= 30;
        }
        else {
            GameProperties.consecutiveSuccesses++;
        }
        this.resetPosition();
    } else {
        this.y -= this.verticalMove;
    }
};

Player.prototype.moveDown = function() {
    if(this.y < this.startingYPosition) {
        this.y += this.verticalMove;
    }
};

Player.prototype.setCharacter = function(sprite) {
    this.sprite = sprite;
};

/**
 * Creates a new PauseScreen class.  This class contains all the information necessary to display the pause screen
 * with all game option information visible to the user.
 * @constructor
 */
var PauseScreen = function() {
    //TODO: consider passing this information into the class or putting it in GameProperties
    this.characterImages = [
        'images/char-boy.png',
        'images/char-cat-girl.png',
        'images/char-horn-girl.png',
        'images/char-pink-girl.png',
        'images/char-princess-girl.png'
    ];

    this.characterSelection = 0;
    this.colouredTileModeOn = false;
};

/**
 * This is called to draw the pause screen on the canvas.
 * The user is allowed to select a character and set which game modes they would like active.
 * There is also a message letting the user know how to exit the pause screen.
 */
PauseScreen.prototype.render = function() {
    this.renderOverlay();
    this.drawTitle("SELECT A CHARACTER", canvas.width/2, 100);
    this.drawCharacterSelect(21, 115, 90);
    this.drawTitle("GAME MODES", canvas.width/2, 330);
    this.drawGameModeText('images/1-icon.png', 'Coloured Tile', this.colouredTileModeOn, 337);
    this.drawGameModeText('images/2-icon.png', 'Collectibles', false, 397);
    this.drawGameModeText('images/3-icon.png', 'Alternate Directions', false, 457);
    this.drawEscapeMessage(555);
};

/**
 * This method draws the background and border of the pause screen so that the game options are more visible to
 * the user.
 */
PauseScreen.prototype.renderOverlay = function() {
    ctx.globalAlpha = 0.85;
    ctx.fillStyle = 'black';
    ctx.fillRect(10, 60, 485, 516);
    ctx.globalAlpha = 1;
    ctx.strokeStyle = 'white';
    ctx.lineWidth = 2;
    ctx.strokeRect(10, 60, 485, 516);
};

/**
 * Draw a grey centered title on the canvas with a black shadow.
 * @param {string} title - the text of the title
 * @param {number} x - the canvas x-coordinate of the middle of the title
 * @param {number} y - the canvas y-coordinate of the title text
 */
PauseScreen.prototype.drawTitle = function(title, x, y) {
    ctx.textAlign = "center";
    ctx.font = "26pt Nunito, sans-serif";
    ctx.fillStyle = 'black';
    // put a shadow behind the title text
    ctx.fillText(title, x+3, y+3);
    ctx.fillStyle = 'grey';
    ctx.fillText(title, x, y);
};

/**
 * Draw the characters available for selection.
 * @param {number} x - the canvas x-coordinate of the left-most character image
 * @param {number} y - the canvas x-coordinate of all the character images
 * @param {number} spacingInterval - the x-coordinate interval to use to evenly space the character images
 */
PauseScreen.prototype.drawCharacterSelect = function(x, y, spacingInterval) {
    ctx.drawImage(Resources.get('images/Selector.png'), this.characterSelection * spacingInterval + x, y);

    for(var characterIndex in this.characterImages) {
        ctx.drawImage(Resources.get(this.characterImages[characterIndex]), characterIndex * spacingInterval + x, y);
    }
};

/**
 * Draw the available game mode text as well as whether the game mode is currently "ON" or "OFF"
 * @param {string} image - the url of the image file
 * @param {string} modeText - the text describing the mode to the user
 * @param {boolean} isOn - true if this game mode is enabled; false if this game mode is disabled
 * @param y - the canvas y-coordinate of where this text should be placed on the canvas
 */
PauseScreen.prototype.drawGameModeText = function(image, modeText, isOn, y) {
    ctx.font = '20pt Nunito, sans-serif';
    ctx.textAlign = 'left';

    var gameModeText = modeText + ' - ';
    if(isOn) {
        // if the game mode is enabled then append ON and colour text green
        ctx.fillStyle = 'green';
        gameModeText += 'ON';
    }
    else {
        // if the game mode is disabled then append OFF and colour text red
        ctx.fillStyle = 'red';
        gameModeText += 'OFF';
    }

    ctx.drawImage(Resources.get(image), 30, y);
    ctx.fillText(gameModeText, 100, y+40);
};

/**
 * Draws the message that lets the user know to press the escape key to exit the pause screen.
 * @param {number} y - the canvas y-coordinate of where the message should be drawn
 */
PauseScreen.prototype.drawEscapeMessage = function(y) {
    ctx.fillStyle = 'white';
    ctx.font = '20pt Nunito, sans-serif';
    ctx.textAlign = 'center';
    ctx.fillText('Press      to play game', canvas.width/2, y);
    ctx.drawImage(Resources.get('images/esc-icon.png'), canvas.width/2 - 72, y-34);
};

/**
 * This function is called by the event listener that is listening for keyUp events when the game is
 * considered 'paused'.  Based on which key was pressed either a new character is selected or a game mode
 * is enabled/disabled.
 * @param {string} input - the string representation of the key that the user pressed
 */
PauseScreen.prototype.handleInput = function (input) {
    switch (input) {
        case 'left':
            if(this.characterSelection > 0) {
                this.characterSelection--;
            }
            break;
        case 'right':
            if(this.characterSelection < this.characterImages.length-1) {
                this.characterSelection++;
            }
            break;
        case 'one':
            //TODO: move this atribute to GameProperties
            this.colouredTileModeOn = !this.colouredTileModeOn;
            GameProperties.currentGamePoints = 0;
            player.resetWalkingArray();
            break;
    }
};

/**
 * Gets the URL of the image for the selected character
 * @returns {string} - image URL of the selected character
 */
PauseScreen.prototype.getSelectedCharacterImageURL = function() {
    return this.characterImages[this.characterSelection];
};

allEnemies = [new Enemy(), new Enemy(), new Enemy(), new Enemy(), new Enemy()];
player = new Player();
pauseScreen = new PauseScreen();

/**
 * This listens for key presses and sends the keys to the Player.handleInput() method.
 */
document.addEventListener('keyup', function(e) {
    var escapeKey = 27;
    //TODO: remove following log message
    console.log(e.keyCode.toString());
    var allowedKeys = {
        37: 'left',
        38: 'up',
        39: 'right',
        40: 'down',
        49: 'one'
    };

    if (e.keyCode == escapeKey) {
        GameProperties.pauseGame = !GameProperties.pauseGame;
    }

    if(GameProperties.pauseGame) {
        pauseScreen.handleInput(allowedKeys[e.keyCode]);
    }
    else {
        player.handleInput(allowedKeys[e.keyCode]);
    }
});
<|endoftext|>


<commit_before>if (!window['$']) var $ = function a(){}
(function a(){
    $.get('https://api.github.com/repos/KaMeHb-UA/LeNode/releases/latest', function(data, status){
        if (status != 'success') a(); else {
            $('a[rel="download"]').attr('href', data.assets[0].browser_download_url);
            $('#latest-version').html(data.tag_name);
            $('*[rel="release-description"]').html(data.name);
        }
    }, 'json');
})();
document.addEventListener('DOMContentLoaded', function(){
    'use strict';
    var actions = {
        log : function(){
            console.log.apply(null, arguments);
            console.log(this);
        },
        hide : function(){
            this.css('display', 'none')
        },
        detach : function(){
            this.detach(arguments ? arguments[0] : undefined)
        },
        remove : function(){
            this.remove(arguments ? arguments[0] : undefined)
        }
    };
    $('*[__click]').each(function(i,e){
        var e = $(e);
        e.click(function(){
            actions[e.attr('__click')].apply(e, (function(a){
                if (a){
                    try{
                        return JSON.parse(a);
                    } catch(e){
                        return [a];
                    }
                } else return [];
            })(e.attr('__click_data')));
        });
    });
});
<commit_msg>Fixing non-existent action<commit_after>if (!window['$']) var $ = function a(){}
(function a(){
    $.get('https://api.github.com/repos/KaMeHb-UA/LeNode/releases/latest', function(data, status){
        if (status != 'success') a(); else {
            $('a[rel="download"]').attr('href', data.assets[0].browser_download_url);
            $('#latest-version').html(data.tag_name);
            $('*[rel="release-description"]').html(data.name);
        }
    }, 'json');
})();
document.addEventListener('DOMContentLoaded', function(){
    'use strict';
    var actions = {
        log : function(){
            console.log.apply(null, arguments);
            console.log(this);
        },
        hide : function(){
            this.css('display', 'none')
        },
        detach : function(){
            this.detach(arguments ? arguments[0] : undefined)
        },
        remove : function(){
            this.remove(arguments ? arguments[0] : undefined)
        }
    };
    $('*[__click]').each(function(i,e){
        var e = $(e);
        e.click(function(){
            try{
                actions[e.attr('__click')].apply(e, (function(a){
                    if (a){
                        try{
                            return JSON.parse(a);
                        } catch(e){
                            return [a];
                        }
                    } else return [];
                })(e.attr('__click_data')));
            } catch(e){
                console.warn('Cannot find action ' + e.attr('__click'));
            }
        });
    });
});
<|endoftext|>


<commit_before>document.addEventListener("DOMContentLoaded", function(event) {

  // Move tools-left container dynamically

  function setMarginLeft() {
    if (window.matchMedia("(min-width: 480px)").matches) {
      var spanLeft = $("#leftBorder");
      var offsetLeft = spanLeft.position().left;
      $("#tools-left").css({
        marginLeft: offsetLeft
      });
    }
  }

  window.addEventListener("resize", setMarginLeft, false);
  window.addEventListener("load", setMarginLeft, true);

  // Move right-hand dropdown menu dynamically

  function setMarginRight() {

    if (window.matchMedia("(min-width: 480px)").matches) {
      var filtersLeft = $("#openFiltersNav");
      var offsetLeft = filtersLeft.position().left;
      $("#toolsNav").css({
        "left": offsetLeft - 16,
        "top": "50px",
        "position": "absolute",
        "display": "block",
        "overflow-y": "auto"
      });
    } else {
      $("#toTop").hide();
    }
  }

  window.addEventListener("resize", setMarginRight, false);
  window.addEventListener("load", setMarginRight, true);

  //Responsive tools navigation
  var opened;

  function openNav() {
    if (typeof opened === "undefined") {
      opened = false;
    }
    if (window.matchMedia("(min-width: 480px)").matches && opened == false) {
      toolsNav.style.visibility = "visible";
      toolsNav.style.height = "100%";
      opened = true;
    } else if (window.matchMedia("(min-width: 480px)").matches && opened == true) {
      toolsNav.style.visibility = "hidden";
      toolsNav.style.height = "0";
      opened = false;
    }
    if (window.matchMedia("(max-width: 479px)").matches) {
      toolsNav.style.visibility = "visible";
      toolsNav.style.height = "100%";
    } else if (window.matchMedia("(max-width: 479px)").matches) {
      toolsNav.style.visibility = "hidden";
      toolsNav.style.height = "0";
    }
    $("#toTop").hide();
  }

  function closeNav() {
    if (window.matchMedia("(max-width: 479px)").matches) {
      toolsNav.style.height = "0%";
    }
  }

  function closeControls() {
    controlsPosition.style.visibility = "hidden";
    controlsZoom.style.visibility = "hidden";
    toolsInfo.style.visibility = "hidden";
    brightenDiv.style.visibility = "hidden";
    sharpenDiv.style.visibility = "hidden"
    grayScaleBtns.style.visibility = "hidden";
    blurDiv.style.visibility = "hidden";
    negativeBtns.style.visibility = "hidden";
    edgeDetectBtns.style.visibility = "hidden";
    embossBtns.style.visibility = "hidden";
  }

  openFiltersNav.addEventListener("click", openNav, false);
  closeFiltersNav.addEventListener("click", closeNav, false);

  // Toggle bottom panel tools
  // Disable unnecessary buttons on bigger screens

  var mq = window.matchMedia("(min-width: 571px)");

  if (mq.matches) {
    $("#togglePosition").attr("disabled", true);
    $("#toggleZoom").attr("disabled", true);
    $("#togglePosition").css({
      "cursor": "auto"
    });
    $("#toggleZoom").css({
      "cursor": "auto"
    });
    toolsInfo.innerHTML = "choose your tool in the left-hand panel";
  }

  function showPositionControls(event) {
    if (mq.matches) {
      event.target.removeEventListener("click", showPositionControls);
    } else {
      controlsPosition.style.visibility = "visible";
    }
  }

  function showZoomControls(event) {
    if (mq.matches) {
      event.target.removeEventListener("click", showZoomControls);
    } else {
      controlsZoom.style.visibility = "visible";
      closeControls();
    }
  }

  togglePosition.addEventListener("click", showPositionControls, false);

  toggleZoom.addEventListener("click", showZoomControls, false);

  toggleGrayscale.addEventListener("click", function(event) {
    closeNav();
    closeControls();
    grayScaleBtns.style.visibility = "visible";
  }, false);

  toggleBrightness.addEventListener("click", function(event) {
    closeNav();
    closeControls();
    brightenDiv.style.visibility = "visible";
  }, false);

  toggleBlur.addEventListener("click", function(event) {
    closeNav();
    closeControls();
    blurDiv.style.visibility = "visible";
  }, false);

  toggleNegative.addEventListener("click", function(event) {
    closeNav();
    closeControls();
    negativeBtns.style.visibility = "visible";
  }, false);

  toggleEdgeDetect.addEventListener("click", function(event) {
    closeNav();
    closeControls();
    edgeDetectBtns.style.visibility = "visible";
  }, false);

  toggleSharpen.addEventListener("click", function(event) {
    closeNav();
    closeControls();
    sharpenDiv.style.visibility = "visible";
  }, false);

  toggleEmboss.addEventListener("click", function(event) {
    closeNav();
    closeControls();
    embossBtns.style.visibility = "visible";
  }, false);

  // Scrolling to sections

  $("#scroll").on("click", function(event) {
    event.preventDefault();
    $("body").animate({
      scrollTop: 411
    }, 500);
    return false;
  });

  $("#about a").on("click", function(event) {
    event.preventDefault();
    $("body").animate({
      scrollTop: 1626
    }, 800);
    return false;
  });

  $("#toTop").on("click", function(event) {
    $("body").animate({
      scrollTop: 0
    }, "slow");
    return false;
  });

  $("#toTop").hide();

  $(document).on("scroll", function(event) {
    if ($("body").scrollTop() > 411) {
      $("#toTop").show();
    } else {
      $("#toTop").hide();
    }
  });

  // Hide toTop

  function hideToTop(event) {
    var pos1 = $("body").scrollTop();
    var pos2 = $("#imgContainer").offset().top;
    var diff = pos2 - pos1;
    if (diff < 50) {
      $("#toTop").hide();
    }
  }
  window.addEventListener("resize", hideToTop, false);
  window.addEventListener("load", hideToTop, false);

  // Put photo on canvas

  function drawNewImage() {
    ctx.clearRect(x, y, canvas.width, canvas.height);

    var MAX_WIDTH = 600;
    var MAX_HEIGHT = 1000;
    var width = userPhoto.width;
    var height = userPhoto.height;

    if (width > height) {
      if (width > MAX_WIDTH) {
        height *= MAX_WIDTH / width;
        width = MAX_WIDTH;
      }
    } else {
      if (height > MAX_HEIGHT) {
        width *= MAX_HEIGHT / height;
        height = MAX_HEIGHT;
      }
    }
    // canvas.width = width;
    // canvas.height = height;

    ctx.drawImage(userPhoto, x, y, userPhoto.width, userPhoto.height, x, y, canvas.width, canvas.height);
    ctx.clearRect(x, y, canvas.width, canvas.height);
  }

  // Upload a photo

  function readURL(input) {

    if (input.files && input.files[0]) {
      var reader = new FileReader();

      reader.onload = function(event) {
        userPhoto.setAttribute("src", event.target.result);

        var MAX_WIDTH = 300;
        var MAX_HEIGHT = 500;
        var width = userPhoto.width;
        var height = userPhoto.height;

        if (width > height) {
          if (width > MAX_WIDTH) {
            height *= MAX_WIDTH / width;
            width = MAX_WIDTH;
          }
        } else {
          if (height > MAX_HEIGHT) {
            width *= MAX_HEIGHT / height;
            height = MAX_HEIGHT;
          }
        }
        canvas.width = width;
        canvas.height = height;
        ctx.drawImage(userPhoto, x, y, width, height);

        var dataurl = canvas.toDataURL("image/png");
        userPhoto.setAttribute("src", dataurl);
      }
      reader.readAsDataURL(input.files[0]);
    }
  }

  $("#inputFile").change(function(event) {
    readURL(this);
    drawNewImage();
    ctx.save();
    $("#resetBtn").next().hide(); //hide "drag&drop" text
  });

  uploadPhoto.addEventListener("click", function(event) {
    $("#inputFile").trigger("click");
  }, false);

  // Filters: GrayScale

  grayScaleOn.addEventListener("click", grayScale, false);

  grayScaleOff.addEventListener("click", function(event) {
    ctx.clearRect(x, y, canvas.width, canvas.height);
    ctx.drawImage(userPhoto, x, y);

  }, false);

  // Filters: Brighten

  brightenRangeSlider.addEventListener("input", brightenImage, false);

  // Filters: Blur

  blurRangeSlider.addEventListener("input", function(event) {
    var iterations = blurRangeSlider.value;
    var imageData = Filters.filterImage(Filters.blur, userPhoto, iterations);
    ctx.putImageData(imageData, x, y, x, y, userPhoto.width, userPhoto.height);

  }, false);

  // Filters: Negative

  negativeOn.addEventListener("click", negativeFilter, false);

  negativeOff.addEventListener("click", function(event) {
    ctx.clearRect(x, y, canvas.width, canvas.height);
    ctx.drawImage(userPhoto, x, y);
    inverted = false;
  }, false);

  // Filters: Edge Detect

  edgeDetectOn.addEventListener("click", function(event) {
    var imageData = Filters.filterImage(Filters.sobel, userPhoto);
    ctx.putImageData(imageData, x, y, x, y, userPhoto.width, userPhoto.height);
  }, false);

  edgeDetectOff.addEventListener("click", function(event) {
    ctx.clearRect(x, y, canvas.width, canvas.height);
    ctx.drawImage(userPhoto, x, y);
  }, false);

  //Filters: Funscale

  sharpenRangeSlider.addEventListener("input", function(event) {
    var iterations = sharpenRangeSlider.value;
    var imageData = Filters.filterImage(Filters.sharpen, userPhoto, iterations);
    ctx.putImageData(imageData, x, y, x, y, userPhoto.width, userPhoto.height);

  }, false);

  // Filters: Emboss

  embossOn.addEventListener("click", function(event) {
    var imageData = Filters.filterImage(Filters.emboss, userPhoto);
    ctx.putImageData(imageData, x, y, x, y, userPhoto.width, userPhoto.height);
  }, false);

  embossOff.addEventListener("click", function(event) {
    ctx.clearRect(x, y, canvas.width, canvas.height);
    ctx.drawImage(userPhoto, x, y);
  }, false);

  // Reset

  resetBtn.addEventListener("click", function(event) {
    ctx.save();
    ctx.clearRect(x - 1, y - 1, canvas.width + 2, canvas.height + 2); //added offsets to clear tidbits
    ctx.restore();
    ctx.drawImage(userPhoto, 0, 0, canvas.width, canvas.height);
  }, false);

  // Download Polaroid

  function downloadCanvas(link, canvasId, filename) {
    link.href = canvas.toDataURL();
    link.download = filename;
  }

  //add Polaroid border

  function borderImage(x) {
    ctx.beginPath();
    ctx.lineWidth = x; // This is your border thickness
    canvas.width += x * 2;
    canvas.height += x * 2;
    ctx.fillStyle = "#fff";
    ctx.strokeStyle = "#fff";

    ctx.rect(0, 0, canvas.width, 30);
    ctx.fillRect(0, 0, canvas.width, canvas.height);
    ctx.fill();
    // ctx.shadowColor = '#999';
    // ctx.shadowBlur = 20;
    // ctx.shadowOffsetX = 15;
    // ctx.shadowOffsetY = 15;
    ctx.drawImage(userPhoto, x, x, canvas.width - 2 * x, canvas.height - 2 * x - 50);
  }

  download.addEventListener("click", function(event) {
    borderImage(20);
    downloadCanvas(this, "imgCanvas", "impossible-photo.png");
    canvas.style.display = "none";
    location.reload();
  }, false);

  // Play Camera Sound

  var audioElement = document.createElement("audio");
  audioElement.setAttribute("src", "sounds/camera.mp3");
  audioElement.setAttribute("autoplay:false", "autoplay");
  audioElement.load();
  $.get();

  download.addEventListener("click", function(event) {
    audioElement.play();
    console.log("ok");
  }, false);

  // Drag & Drop

  var dropzone = $("#resetBtn").next();

  dropzone.on('dragover', function() {
    //add hover class when drag over
    dropzone.addClass('hover');
    return false;
  });

  dropzone.on('dragleave', function() {
    //remove hover class when drag out
    dropzone.removeClass('hover');
    return false;
  });

  dropzone.on('drop', function(e) {
    //prevent browser from open the file when drop off
    e.stopPropagation();
    e.preventDefault();
    dropzone.removeClass('hover');
    $("#inputFile").trigger("click");
    //retrieve uploaded files data
    var files = e.originalEvent.dataTransfer.files;

    return false;
  });

  //end
});<commit_msg>Drag/drop working.<commit_after>document.addEventListener("DOMContentLoaded", function(event) {

  // Move tools-left container dynamically

  function setMarginLeft() {
    if (window.matchMedia("(min-width: 480px)").matches) {
      var spanLeft = $("#leftBorder");
      var offsetLeft = spanLeft.position().left;
      $("#tools-left").css({
        marginLeft: offsetLeft
      });
    }
  }

  window.addEventListener("resize", setMarginLeft, false);
  window.addEventListener("load", setMarginLeft, true);

  // Move right-hand dropdown menu dynamically

  function setMarginRight() {

    if (window.matchMedia("(min-width: 480px)").matches) {
      var filtersLeft = $("#openFiltersNav");
      var offsetLeft = filtersLeft.position().left;
      $("#toolsNav").css({
        "left": offsetLeft - 16,
        "top": "50px",
        "position": "absolute",
        "display": "block",
        "overflow-y": "auto"
      });
    } else {
      $("#toTop").hide();
    }
  }

  window.addEventListener("resize", setMarginRight, false);
  window.addEventListener("load", setMarginRight, true);

  //Responsive tools navigation
  var opened;

  function openNav() {
    if (typeof opened === "undefined") {
      opened = false;
    }
    if (window.matchMedia("(min-width: 480px)").matches && opened == false) {
      toolsNav.style.visibility = "visible";
      toolsNav.style.height = "100%";
      opened = true;
    } else if (window.matchMedia("(min-width: 480px)").matches && opened == true) {
      toolsNav.style.visibility = "hidden";
      toolsNav.style.height = "0";
      opened = false;
    }
    if (window.matchMedia("(max-width: 479px)").matches) {
      toolsNav.style.visibility = "visible";
      toolsNav.style.height = "100%";
    } else if (window.matchMedia("(max-width: 479px)").matches) {
      toolsNav.style.visibility = "hidden";
      toolsNav.style.height = "0";
    }
    $("#toTop").hide();
  }

  function closeNav() {
    if (window.matchMedia("(max-width: 479px)").matches) {
      toolsNav.style.height = "0%";
    }
  }

  function closeControls() {
    controlsPosition.style.visibility = "hidden";
    controlsZoom.style.visibility = "hidden";
    toolsInfo.style.visibility = "hidden";
    brightenDiv.style.visibility = "hidden";
    sharpenDiv.style.visibility = "hidden"
    grayScaleBtns.style.visibility = "hidden";
    blurDiv.style.visibility = "hidden";
    negativeBtns.style.visibility = "hidden";
    edgeDetectBtns.style.visibility = "hidden";
    embossBtns.style.visibility = "hidden";
  }

  openFiltersNav.addEventListener("click", openNav, false);
  closeFiltersNav.addEventListener("click", closeNav, false);

  // Toggle bottom panel tools
  // Disable unnecessary buttons on bigger screens

  var mq = window.matchMedia("(min-width: 571px)");

  if (mq.matches) {
    $("#togglePosition").attr("disabled", true);
    $("#toggleZoom").attr("disabled", true);
    $("#togglePosition").css({
      "cursor": "auto"
    });
    $("#toggleZoom").css({
      "cursor": "auto"
    });
    toolsInfo.innerHTML = "choose your tool in the left-hand panel";
  }

  function showPositionControls(event) {
    if (mq.matches) {
      event.target.removeEventListener("click", showPositionControls);
    } else {
      controlsPosition.style.visibility = "visible";
    }
  }

  function showZoomControls(event) {
    if (mq.matches) {
      event.target.removeEventListener("click", showZoomControls);
    } else {
      controlsZoom.style.visibility = "visible";
      closeControls();
    }
  }

  togglePosition.addEventListener("click", showPositionControls, false);

  toggleZoom.addEventListener("click", showZoomControls, false);

  toggleGrayscale.addEventListener("click", function(event) {
    closeNav();
    closeControls();
    grayScaleBtns.style.visibility = "visible";
  }, false);

  toggleBrightness.addEventListener("click", function(event) {
    closeNav();
    closeControls();
    brightenDiv.style.visibility = "visible";
  }, false);

  toggleBlur.addEventListener("click", function(event) {
    closeNav();
    closeControls();
    blurDiv.style.visibility = "visible";
  }, false);

  toggleNegative.addEventListener("click", function(event) {
    closeNav();
    closeControls();
    negativeBtns.style.visibility = "visible";
  }, false);

  toggleEdgeDetect.addEventListener("click", function(event) {
    closeNav();
    closeControls();
    edgeDetectBtns.style.visibility = "visible";
  }, false);

  toggleSharpen.addEventListener("click", function(event) {
    closeNav();
    closeControls();
    sharpenDiv.style.visibility = "visible";
  }, false);

  toggleEmboss.addEventListener("click", function(event) {
    closeNav();
    closeControls();
    embossBtns.style.visibility = "visible";
  }, false);

  // Scrolling to sections

  $("#scroll").on("click", function(event) {
    event.preventDefault();
    $("body").animate({
      scrollTop: 411
    }, 500);
    return false;
  });

  $("#about a").on("click", function(event) {
    event.preventDefault();
    $("body").animate({
      scrollTop: 1626
    }, 800);
    return false;
  });

  $("#toTop").on("click", function(event) {
    $("body").animate({
      scrollTop: 0
    }, "slow");
    return false;
  });

  $("#toTop").hide();

  $(document).on("scroll", function(event) {
    if ($("body").scrollTop() > 411) {
      $("#toTop").show();
    } else {
      $("#toTop").hide();
    }
  });

  // Hide toTop

  function hideToTop(event) {
    var pos1 = $("body").scrollTop();
    var pos2 = $("#imgContainer").offset().top;
    var diff = pos2 - pos1;
    if (diff < 50) {
      $("#toTop").hide();
    }
  }
  window.addEventListener("resize", hideToTop, false);
  window.addEventListener("load", hideToTop, false);

  // Put photo on canvas

  function drawNewImage() {
    ctx.clearRect(x, y, canvas.width, canvas.height);

    var MAX_WIDTH = 600;
    var MAX_HEIGHT = 1000;
    var width = userPhoto.width;
    var height = userPhoto.height;

    if (width > height) {
      if (width > MAX_WIDTH) {
        height *= MAX_WIDTH / width;
        width = MAX_WIDTH;
      }
    } else {
      if (height > MAX_HEIGHT) {
        width *= MAX_HEIGHT / height;
        height = MAX_HEIGHT;
      }
    }
    // canvas.width = width;
    // canvas.height = height;

    ctx.drawImage(userPhoto, x, y, userPhoto.width, userPhoto.height, x, y, canvas.width, canvas.height);
    ctx.clearRect(x, y, canvas.width, canvas.height);
  }

  // Upload a photo

  function readURL(input) {

    if (input.files && input.files[0]) {
      var reader = new FileReader();

      reader.onload = function(event) {
        userPhoto.setAttribute("src", event.target.result);

        var MAX_WIDTH = 300;
        var MAX_HEIGHT = 500;
        var width = userPhoto.width;
        var height = userPhoto.height;

        if (width > height) {
          if (width > MAX_WIDTH) {
            height *= MAX_WIDTH / width;
            width = MAX_WIDTH;
          }
        } else {
          if (height > MAX_HEIGHT) {
            width *= MAX_HEIGHT / height;
            height = MAX_HEIGHT;
          }
        }
        canvas.width = width;
        canvas.height = height;
        ctx.drawImage(userPhoto, x, y, width, height);

        var dataurl = canvas.toDataURL("image/png");
        userPhoto.setAttribute("src", dataurl);
      }
      reader.readAsDataURL(input.files[0]);
    }
  }

  $("#inputFile").change(function(event) {
    readURL(this);
    drawNewImage();
    ctx.save();
    $("#resetBtn").next().hide(); //hide "drag&drop" text
  });

  uploadPhoto.addEventListener("click", function(event) {
    $("#inputFile").trigger("click");
  }, false);

  // Filters: GrayScale

  grayScaleOn.addEventListener("click", grayScale, false);

  grayScaleOff.addEventListener("click", function(event) {
    ctx.clearRect(x, y, canvas.width, canvas.height);
    ctx.drawImage(userPhoto, x, y);

  }, false);

  // Filters: Brighten

  brightenRangeSlider.addEventListener("input", brightenImage, false);

  // Filters: Blur

  blurRangeSlider.addEventListener("input", function(event) {
    var iterations = blurRangeSlider.value;
    var imageData = Filters.filterImage(Filters.blur, userPhoto, iterations);
    ctx.putImageData(imageData, x, y, x, y, userPhoto.width, userPhoto.height);

  }, false);

  // Filters: Negative

  negativeOn.addEventListener("click", negativeFilter, false);

  negativeOff.addEventListener("click", function(event) {
    ctx.clearRect(x, y, canvas.width, canvas.height);
    ctx.drawImage(userPhoto, x, y);
    inverted = false;
  }, false);

  // Filters: Edge Detect

  edgeDetectOn.addEventListener("click", function(event) {
    var imageData = Filters.filterImage(Filters.sobel, userPhoto);
    ctx.putImageData(imageData, x, y, x, y, userPhoto.width, userPhoto.height);
  }, false);

  edgeDetectOff.addEventListener("click", function(event) {
    ctx.clearRect(x, y, canvas.width, canvas.height);
    ctx.drawImage(userPhoto, x, y);
  }, false);

  //Filters: Funscale

  sharpenRangeSlider.addEventListener("input", function(event) {
    var iterations = sharpenRangeSlider.value;
    var imageData = Filters.filterImage(Filters.sharpen, userPhoto, iterations);
    ctx.putImageData(imageData, x, y, x, y, userPhoto.width, userPhoto.height);

  }, false);

  // Filters: Emboss

  embossOn.addEventListener("click", function(event) {
    var imageData = Filters.filterImage(Filters.emboss, userPhoto);
    ctx.putImageData(imageData, x, y, x, y, userPhoto.width, userPhoto.height);
  }, false);

  embossOff.addEventListener("click", function(event) {
    ctx.clearRect(x, y, canvas.width, canvas.height);
    ctx.drawImage(userPhoto, x, y);
  }, false);

  // Reset

  resetBtn.addEventListener("click", function(event) {
    ctx.save();
    ctx.clearRect(x - 1, y - 1, canvas.width + 2, canvas.height + 2); //added offsets to clear tidbits
    ctx.restore();
    ctx.drawImage(userPhoto, 0, 0, canvas.width, canvas.height);
  }, false);

  // Download Polaroid

  function downloadCanvas(link, canvasId, filename) {
    link.href = canvas.toDataURL();
    link.download = filename;
  }

  //add Polaroid border

  function borderImage(x) {
    ctx.beginPath();
    ctx.lineWidth = x; // This is your border thickness
    canvas.width += x * 2;
    canvas.height += x * 2;
    ctx.fillStyle = "#fff";
    ctx.strokeStyle = "#fff";

    ctx.rect(0, 0, canvas.width, 30);
    ctx.fillRect(0, 0, canvas.width, canvas.height);
    ctx.fill();
    // ctx.shadowColor = '#999';
    // ctx.shadowBlur = 20;
    // ctx.shadowOffsetX = 15;
    // ctx.shadowOffsetY = 15;
    ctx.drawImage(userPhoto, x, x, canvas.width - 2 * x, canvas.height - 2 * x - 50);
  }

  download.addEventListener("click", function(event) {
    borderImage(20);
    downloadCanvas(this, "imgCanvas", "impossible-photo.png");
    canvas.style.display = "none";
    location.reload();
  }, false);

  // Play Camera Sound

  var audioElement = document.createElement("audio");
  audioElement.setAttribute("src", "sounds/camera.mp3");
  audioElement.setAttribute("autoplay:false", "autoplay");
  audioElement.load();
  $.get();

  download.addEventListener("click", function(event) {
    audioElement.play();
    console.log("ok");
  }, false);

  // Drag & Drop

  var dropzone = $("#imgContainer");

  dropzone.on('dragover', function() {
    //add hover class when drag over
    dropzone.addClass('hover');
    return false;
  });

  dropzone.on('dragleave', function() {
    //remove hover class when drag out
    dropzone.removeClass('hover');
    return false;
  });

  dropzone.on('drop', function(e) {
    //prevent browser from open the file when drop off
    e.stopPropagation();
    e.preventDefault();
    dropzone.removeClass('hover');
    //retrieve uploaded files data
    var files = e.originalEvent.dataTransfer;
  processFiles(files);

    return false;
  });

  function processFiles(files) {
    //check for browser support
    if (files && typeof FileReader !== "undefined") {
      //extract FileList as File object
      readURL(files);
      drawNewImage();
      ctx.save();
      console.log("file");
    } else {
      //some message or fallback
      console.log("drag error");
    }
  }

  //end
});<|endoftext|>


<commit_before>'use strict';

function IssueDetailView(issue) {
  this.issue = issue;
}

IssueDetailView.prototype.render = function() {
  var container = $('.issue-detail');
  var backButton = $("

");
  backButton.click(this.hide);
  container.append(backButton);

  var title = $("

"+ this.issue.title +"

");
  var issueNumber = $("

#"+ this.issue.number +"

");
  var text = $("

" + prepareBody(this.issue.body) + "

");
  container.append(issueNumber);
  container.append(title);
  container.append($("
"));
  container.append(text);
  $(container).show();
  $(".issue-list").hide();

  function prepareBody(body) {
    return markdown.toHTML(body);
  }
}

IssueDetailView.prototype.hide = function() {
  $(".issue-list").show();
  $(".issue-detail").hide();
  $(".issue-detail").empty();
};

(function() {
  var issueDetailView = null;

  function repoName() {
    return $('#repositoryName').val().toString();
  }

  function renderListView(repoName) {
    if(!repoName) {
      throw new Error("expected repoName");
    }
    var db = new PouchDB(repoName);
    db.allDocs({ include_docs: true })
      .then(function(docs) {
        $(".issue-list").empty();
        var plainDocs = _.map(docs.rows, function(d) { return d.doc; });
        var views = _.map(plainDocs, renderIssueView);
        $(".issue-list").append(views);
      });

    function renderIssueView(issue) {
      var container = $("");
      var heading = $("

")
      container.attr('id', issue.id);
      heading.html("#" + issue.number + " " + issue.title);
      container.append(heading);
      container.click(showIssueDetail);
      return container;
    }

    function showIssueDetail(ev) {
      var id = $(this).attr('id');
      var db = new PouchDB(repoName);
      db.get(id)
        .then(function(issue) {
          issueDetailView = new IssueDetailView(issue);
          issueDetailView.render();
        })
        .catch(function(err) {
          console.log("ERR", err);
          new ErrorBanner(err);
        });
    }
  }

  function fetchIssues(ev) {
    ev.preventDefault();
    var repo = repoName();
    if(!repo || repo === "") {
      return;
    }

    if(issueDetailView) {
      issueDetailView.hide();
      issueDetailView = null;
    }

    var gh = new GitHub();
    gh.getIssues(repo).listIssues()
      .then(function(resultSet) {
        var db = new PouchDB(repo);
        return db.bulkDocs(_.map(resultSet.data, setDocId));
      })
      .then(function(){
        renderListView(repo);
        $(".add-new-repo").hide();
      })
      .catch(function(err) {
        console.log("ERR", err);
        new ErrorBanner("Fetching issues for " + repo + " failed");
      });

    function setDocId(issue) {
      issue['_id'] = issue.id.toString();
      return issue;
    }
  }

  function loadAvailableRepositories() {
    PouchDB.allDbs().then(function (dbs) {
      var dbEntries = dbs.map(function(db) {
        var dbEntry = $("" + db + "");
        dbEntry.click(function(ev) {
          renderListView(db);
          $('.available-repos').hide();
        });
        return dbEntry;
      });
      $(".repository-list").append(dbEntries);
    }).catch(function (err) {
      console.error("Failed to fetch all databases", err);
      new ErrorBanner("Failed to fetch all databases");
    });
  }

  function ErrorBanner(message) {
    this.timeoutHandler = null;

    $(".error-banner").html(message);
    $('.error-banner').show();

    this.hideError = function() {
      $(".error-banner").html('');
      $('.error-banner').hide();
      window.clearTimeout(this.timeoutHandler);
      this.timeoutHandler = null;
    }
    this.timeoutHandler = setTimeout(this.hideError, 1000 * 5);
  }

  $(document).ready(function() {
    $('.fetch-issues').click(fetchIssues);
    loadAvailableRepositories();
    $(".show-available-repo-button").click(function() {
      $(".available-repos").toggle();
      $(".add-new-repo").hide();
    });

    $(".add-repo-button").click(function() {
      $(".add-new-repo").toggle();
      $(".available-repos").hide();
    });
  });
})();<commit_msg>empty issue list every time when fetching issues<commit_after>'use strict';

function IssueDetailView(issue) {
  this.issue = issue;
}

IssueDetailView.prototype.render = function() {
  var container = $('.issue-detail');
  var backButton = $("

");
  backButton.click(this.hide);
  container.append(backButton);

  var title = $("

"+ this.issue.title +"

");
  var issueNumber = $("

#"+ this.issue.number +"

");
  var text = $("

" + prepareBody(this.issue.body) + "

");
  container.append(issueNumber);
  container.append(title);
  container.append($("
"));
  container.append(text);
  $(container).show();
  $(".issue-list").hide();

  function prepareBody(body) {
    return markdown.toHTML(body);
  }
}

IssueDetailView.prototype.hide = function() {
  $(".issue-list").show();
  $(".issue-detail").hide();
  $(".issue-detail").empty();
};

(function() {
  var issueDetailView = null;

  function repoName() {
    return $('#repositoryName').val().toString();
  }

  function renderListView(repoName) {
    if(!repoName) {
      throw new Error("expected repoName");
    }
    var db = new PouchDB(repoName);
    db.allDocs({ include_docs: true })
      .then(function(docs) {
        $(".issue-list").empty();
        var plainDocs = _.map(docs.rows, function(d) { return d.doc; });
        var views = _.map(plainDocs, renderIssueView);
        $(".issue-list").append(views);
      });

    function renderIssueView(issue) {
      var container = $("");
      var heading = $("

")
      container.attr('id', issue.id);
      heading.html("#" + issue.number + " " + issue.title);
      container.append(heading);
      container.click(showIssueDetail);
      return container;
    }

    function showIssueDetail(ev) {
      var id = $(this).attr('id');
      var db = new PouchDB(repoName);
      db.get(id)
        .then(function(issue) {
          issueDetailView = new IssueDetailView(issue);
          issueDetailView.render();
        })
        .catch(function(err) {
          console.log("ERR", err);
          new ErrorBanner(err);
        });
    }
  }

  function fetchIssues(ev) {
    ev.preventDefault();
    var repo = repoName();
    if(!repo || repo === "") {
      return;
    }

    if(issueDetailView) {
      issueDetailView.hide();
      issueDetailView = null;
    }
    $(".issue-list").empty();

    var gh = new GitHub();
    gh.getIssues(repo).listIssues()
      .then(function(resultSet) {
        var db = new PouchDB(repo);
        return db.bulkDocs(_.map(resultSet.data, setDocId));
      })
      .then(function(){
        renderListView(repo);
        $(".add-new-repo").hide();
      })
      .catch(function(err) {
        console.log("ERR", err);
        new ErrorBanner("Fetching issues for " + repo + " failed");
      });

    function setDocId(issue) {
      issue['_id'] = issue.id.toString();
      return issue;
    }
  }

  function loadAvailableRepositories() {
    PouchDB.allDbs().then(function (dbs) {
      var dbEntries = dbs.map(function(db) {
        var dbEntry = $("" + db + "");
        dbEntry.click(function(ev) {
          renderListView(db);
          $('.available-repos').hide();
        });
        return dbEntry;
      });
      $(".repository-list").append(dbEntries);
    }).catch(function (err) {
      console.error("Failed to fetch all databases", err);
      new ErrorBanner("Failed to fetch all databases");
    });
  }

  function ErrorBanner(message) {
    this.timeoutHandler = null;

    $(".error-banner").html(message);
    $('.error-banner').show();

    this.hideError = function() {
      $(".error-banner").html('');
      $('.error-banner').hide();
      window.clearTimeout(this.timeoutHandler);
      this.timeoutHandler = null;
    }
    this.timeoutHandler = setTimeout(this.hideError, 1000 * 5);
  }

  $(document).ready(function() {
    $('.fetch-issues').click(fetchIssues);
    loadAvailableRepositories();
    $(".show-available-repo-button").click(function() {
      $(".available-repos").toggle();
      $(".add-new-repo").hide();
    });

    $(".add-repo-button").click(function() {
      $(".add-new-repo").toggle();
      $(".available-repos").hide();
    });
  });
})();<|endoftext|>


<commit_before>(function(){
    //initiate the client
    var oh = Ohmage("/app", "campaign-manager")

    //debugging
    window.oh = oh;

    //attach global callbacks
    oh.callback("done", function(x, status, req){
        //for debugging only
        //console.log(x);
    })

    //global error handler. In ohmage 200 means unauthenticated
    oh.callback("error", function(msg, code, req){
        (code == 200) ? window.location.replace("../web/#login") : message("Error! " + msg);
    });

    //prevent timeout
    oh.keepalive();

    //get data
    oh.user.whoami().done(function(username){
        updateProgress(10)
        oh.campaign.readall().done(function(data){
            updateProgress(15)
            $("#progressdiv").removeClass("hidden");
            var urns = Object.keys(data);
            var progress = 0;
            var total = 0;
            var requests = $.map(urns.sort(), function(urn, i){
                var roles = data[urn]["user_roles"];
                if($.inArray("author", roles) > -1 || $.inArray("supervisor", roles) > -1) {

                    var count = -1;
                    total++;

                    var tr = $("
").appendTo("#campaigntablebody")
                    var td5 = $("").appendTo(tr);
                    var td1 = $("").appendTo(tr).text(data[urn].name);
                    var td2 = $("").appendTo(tr).text(data[urn].creation_timestamp);
                    var td3 = $("").appendTo(tr).text(data[urn].running_state);
                    var td4 = $("").appendTo(tr);

                    var btn = $("
").addClass("btn-group").append('\
                        <button type="button" class="btn btn-primary btn-sm dropdown-toggle" data-toggle="dropdown"> \
                        </button>').appendTo(td5);

                    var ul = $("
").addClass("dropdown-menu").attr("role", "menu").appendTo(btn);

                    var a2 = $("").appendTo($("
").appendTo(ul)).append(' Edit Campaign').attr("href", "#").click(function(e){
                        e.preventDefault();
                        if(count < 0){
                            message("Loading campaign info, please be patient.", "info")
                        } else if(count > 0){
                            message("Campaign " + urn + " has existing responses and can therefore not be modified.")
                        } else {
                            window.location.href = '../surveytool/#' + urn;
                        }
                    });

                    var a3 = $("").appendTo($("
").appendTo(ul)).append(' Visualize').attr("href", "#").click(function(e){
                        e.preventDefault();
                        if(count < 0){
                            message("Loading campaign info, please be patient.", "info")
                        } else if(count === 0){
                            message("Campaign " + urn + " has no existing responses. Nothing to visualize.")
                        } else {
                            window.location.href = '../dashboard/#' + urn;
                        }
                    });

                    var a4 = $("").appendTo($("
").appendTo(ul)).append(' Download XML').attr("href", "#").click(function(e){
                        e.preventDefault();
                        $("#hiddenurn").val(urn)
                        $("#hiddenform").submit()
                    });

                    var a5 = $("").appendTo($("
").appendTo(ul)).append(' Export Data')
                        .attr("href", "../../app/survey_response/read?campaign_urn=" + urn + "&privacy_state=shared&client=manager&user_list=urn:ohmage:special:all&prompt_id_list=urn:ohmage:special:all&output_format=csv&sort_oder=timestamp&column_list=urn:ohmage:user:id,urn:ohmage:context:timestamp,urn:ohmage:prompt:response,urn:ohmage:context:location:latitude,urn:ohmage:context:location:longitude&suppress_metadata=true")

                    ul.append($("
").addClass('divider'))

                    var a1 = $("").appendTo($("
").appendTo(ul)).append(' Settings').attr("href", "#").click(function(e){
                        e.preventDefault();
                        populateModal();
                    });

                    function populateModal(){
                        oh.campaign.readall({
                            campaign_urn_list : urn,
                            output_format:"long"
                        }).done(function(x){
                            var longdata = x[urn];
                            $("#campaign_name").val(longdata.name);
                            $("#campaign_description").val(longdata.description);
                            $("#campaign_urn").val(urn);

                            //$("#campaign_running")[0].checked = (data["running_state"] == "running");
                            //$("#campaign_privacy")[0].checked = (data["privacy_state"] == "shared");

                            $("#campaign_running").bootstrapSwitch({size: "small", onColor: "success", offColor: "danger", onText:"running", offText:"stopped"})
                            $("#campaign_privacy").bootstrapSwitch({size: "small", onColor: "success", offColor: "danger", onText:"enabled", offText:"disabled"})
                            $("#campaign_privacy").bootstrapSwitch("state", longdata["privacy_state"] == "shared");
                            $("#campaign_running").bootstrapSwitch("state", longdata["running_state"] == "running");

                            $("#campaign_class option").each(function(i){
                                $(this).prop("selected", $.inArray($(this).attr("value"), longdata.classes) > -1);
                            });
                            $("#campaign_class").trigger("chosen:updated");

                            if(count){
                                $(".xml-upload-form").hide();
                            }

                            $('#myModal').modal("show").on("shown.bs.modal", function(){
                                $("#campaign_class").chosen({search_contains:true, no_results_text: "Class not found."});
                                $(".xml-upload-form").fileinput();
                            });

                            var xmldata;
                            $("input.xml-file-input").on("change", function(){
                                var f = this.files[0];
                                if(f){
                                    var r = new FileReader();
                                    r.onload = function(e) {
                                        xmldata = r.result;
                                    }
                                    r.readAsText(f);
                                } else {
                                    xmldata = null;
                                }
                            })

                            $("#campaign_delete_button").unbind("click").click(function(e){
                                e.preventDefault();

                                // test for existing responses
                                if(count && !confirm("This campaign has " + count + " responses. Are you sure?")){
                                    return;
                                }

                                var btn = $(this).attr("disabled", "disabled");
                                oh.campaign.delete({campaign_urn:urn}).done(function(){
                                    $('#myModal').modal("hide");
                                    tr.hide("slow", function(){
                                        alert("Campaign " + urn + " deleted!")
                                    });
                                }).always(function(){
                                    btn.removeAttr("disabled");
                                });
                            });

                            $("#campaign_save_button").unbind("click").click(function(e){
                                e.preventDefault();
                                var btn = $(this).attr("disabled", "disabled");
                                var running_state = $("#campaign_running")[0].checked ? "running" : "stopped";
                                var privacy_state = $("#campaign_privacy")[0].checked ? "shared" : "private";
                                var args = {
                                    campaign_urn : urn,
                                    running_state : running_state,
                                    privacy_state : privacy_state,
                                    description : $("#campaign_description").val(),
                                    class_list_remove : longdata.classes,
                                    class_list_add : $("#campaign_class").val()
                                }

                                //update xml only if selected
                                if(xmldata){
                                    args.xml = fixxml(xmldata, longdata.name ,urn);
                                }

                                oh.campaign.update(args).done(function(){
                                    td3.text(running_state);
                                    $('#myModal').modal("hide")
                                }).always(function(){
                                    btn.removeAttr("disabled");
                                });
                            });
                        });
                    }

                    // Disable for current deployment because confusing?
                    //a3.hide()
                    //a4.hide()
                    //a5.hide()

                    return oh.survey.count(urn).done(function(counts){
                        if(!Object.keys(counts).length){
                            //no existing responses found
                            count = 0;
                        } else {
                            count = $.map(counts, function(val, key) {
                                return val[0].count;
                            }).reduce(function(previousValue, currentValue) {
                                return previousValue + currentValue;
                            });
                        }
                        td4.text(count);
                    }).always(function(){
                        updateProgress((progress++/total) * 75 + 25);
                    });
                }
            });

            //data tables widget
            function initTable(){
                $('#campaigntable').dataTable( {
                    "dom" : '<"pull-right"l><"pull-left"f>tip',
                    "lengthMenu": [[25, 50, 100, -1], [25, 50, 100, "All"]],
                    "aoColumnDefs": [
                       { 'bSortable': false, 'aTargets': [ 0 ] }
                    ]
                });
            }

            //init temporary datatable
            initTable()

            //reinit final datatable after counts have been updated
            $.when.apply($, requests).always(function() {
                $("#progressdiv").addClass("hidden");
                $('#campaigntable').dataTable().fnDestroy();
                initTable();
            });

            //resetters
            $("#myModal").on("hidden.bs.modal", function(){
                $(".xml-upload-form").show();
                //$(".fileinput").fileinput("clear");
            })
        });

        //get users
        oh.user.read().done(function(x){
            $.each(Object.keys(x).sort(), function( i, name ) {
                //$("#campaign_author").append($("<option />").text(name));
            });
        });

        //get classes
        oh.class.read().done(function(x){
            $.each(Object.keys(x).sort(), function( i, urn ) {
                $("#campaign_class").append($("<option />").text(urn).attr("value", urn));
            });
        });
    });

    updateProgress = _.throttle(function(pct){
        $(".progress-bar").css("width", + pct + "%");
    }, 300);

    function message(msg, type){
        // type must be one of success, info, warning, danger
        type = type || "danger"
        $("#errordiv").empty().append('
×' + msg + '
');
        $('html, body').animate({
           scrollTop: 100
        }, 200);
    }

    //XML parser for mixed case tag names (HTML only supports lowercase tags)
    var parse = (function(parser, jQuery){
        return function(str) {
            return jQuery(parser.parseFromString(str, "text/xml").documentElement)
        }
    })(new DOMParser(), jQuery)

    function fixxml(input, name, urn){
        var xml = $.parseXML(input);
        var campaign = $("campaign", xml);
        campaign.children("campaignName").remove();
        campaign.children("campaignUrn").remove();
        campaign.prepend(parse("<campaignName/>").text(name))
        campaign.prepend(parse("<campaignUrn/>").text(urn))
        return (new XMLSerializer()).serializeToString(xml);
    }

})();
<commit_msg>add link to responses<commit_after>(function(){
    //initiate the client
    var oh = Ohmage("/app", "campaign-manager")

    //debugging
    window.oh = oh;

    //attach global callbacks
    oh.callback("done", function(x, status, req){
        //for debugging only
        //console.log(x);
    })

    //global error handler. In ohmage 200 means unauthenticated
    oh.callback("error", function(msg, code, req){
        (code == 200) ? window.location.replace("../web/#login") : message("Error! " + msg);
    });

    //prevent timeout
    oh.keepalive();

    //get data
    oh.user.whoami().done(function(username){
        updateProgress(10)
        oh.campaign.readall().done(function(data){
            updateProgress(15)
            $("#progressdiv").removeClass("hidden");
            var urns = Object.keys(data);
            var progress = 0;
            var total = 0;
            var requests = $.map(urns.sort(), function(urn, i){
                var roles = data[urn]["user_roles"];
                if($.inArray("author", roles) > -1 || $.inArray("supervisor", roles) > -1) {

                    var count = -1;
                    total++;

                    var tr = $("
").appendTo("#campaigntablebody")
                    var td5 = $("").appendTo(tr);
                    var td1 = $("").appendTo(tr).text(data[urn].name);
                    var td2 = $("").appendTo(tr).text(data[urn].creation_timestamp);
                    var td3 = $("").appendTo(tr).text(data[urn].running_state);
                    var td4 = $("").appendTo(tr);

                    var btn = $("
").addClass("btn-group").append('\
                        <button type="button" class="btn btn-primary btn-sm dropdown-toggle" data-toggle="dropdown"> \
                        </button>').appendTo(td5);

                    var ul = $("
").addClass("dropdown-menu").attr("role", "menu").appendTo(btn);

                    var a2 = $("").appendTo($("
").appendTo(ul)).append(' Edit Campaign').attr("href", "#").click(function(e){
                        e.preventDefault();
                        if(count < 0){
                            message("Loading campaign info, please be patient.", "info")
                        } else if(count > 0){
                            message("Campaign " + urn + " has existing responses and can therefore not be modified.")
                        } else {
                            window.location.href = '../surveytool/#' + urn;
                        }
                    });

                    var a3 = $("").appendTo($("
").appendTo(ul)).append(' Visualize').attr("href", "#").click(function(e){
                        e.preventDefault();
                        if(count < 0){
                            message("Loading campaign info, please be patient.", "info")
                        } else if(count === 0){
                            message("Campaign " + urn + " has no existing responses. Nothing to visualize.")
                        } else {
                            window.location.href = '../dashboard/#' + urn;
                        }
                    });

                    var responselink = $("").appendTo($("
").appendTo(ul)).append(' Responses').attr("href", "#").click(function(e){
                        e.preventDefault();
                        if(count < 0){
                            message("Loading campaign info, please be patient.", "info")
                        } else if(count === 0){
                            message("Campaign " + urn + " has no existing responses.")
                        } else {
                            window.location.href = '../responsetool/#' + urn;
                        }
                    });

                    var a4 = $("").appendTo($("
").appendTo(ul)).append(' Download XML').attr("href", "#").click(function(e){
                        e.preventDefault();
                        $("#hiddenurn").val(urn)
                        $("#hiddenform").submit()
                    });

                    var a5 = $("").appendTo($("
").appendTo(ul)).append(' Export Data')
                        .attr("href", "../../app/survey_response/read?campaign_urn=" + urn + "&privacy_state=shared&client=manager&user_list=urn:ohmage:special:all&prompt_id_list=urn:ohmage:special:all&output_format=csv&sort_oder=timestamp&column_list=urn:ohmage:user:id,urn:ohmage:context:timestamp,urn:ohmage:prompt:response,urn:ohmage:context:location:latitude,urn:ohmage:context:location:longitude&suppress_metadata=true")

                    ul.append($("
").addClass('divider'))

                    var a1 = $("").appendTo($("
").appendTo(ul)).append(' Settings').attr("href", "#").click(function(e){
                        e.preventDefault();
                        populateModal();
                    });

                    function populateModal(){
                        oh.campaign.readall({
                            campaign_urn_list : urn,
                            output_format:"long"
                        }).done(function(x){
                            var longdata = x[urn];
                            $("#campaign_name").val(longdata.name);
                            $("#campaign_description").val(longdata.description);
                            $("#campaign_urn").val(urn);

                            //$("#campaign_running")[0].checked = (data["running_state"] == "running");
                            //$("#campaign_privacy")[0].checked = (data["privacy_state"] == "shared");

                            $("#campaign_running").bootstrapSwitch({size: "small", onColor: "success", offColor: "danger", onText:"running", offText:"stopped"})
                            $("#campaign_privacy").bootstrapSwitch({size: "small", onColor: "success", offColor: "danger", onText:"enabled", offText:"disabled"})
                            $("#campaign_privacy").bootstrapSwitch("state", longdata["privacy_state"] == "shared");
                            $("#campaign_running").bootstrapSwitch("state", longdata["running_state"] == "running");

                            $("#campaign_class option").each(function(i){
                                $(this).prop("selected", $.inArray($(this).attr("value"), longdata.classes) > -1);
                            });
                            $("#campaign_class").trigger("chosen:updated");

                            if(count){
                                $(".xml-upload-form").hide();
                            }

                            $('#myModal').modal("show").on("shown.bs.modal", function(){
                                $("#campaign_class").chosen({search_contains:true, no_results_text: "Class not found."});
                                $(".xml-upload-form").fileinput();
                            });

                            var xmldata;
                            $("input.xml-file-input").on("change", function(){
                                var f = this.files[0];
                                if(f){
                                    var r = new FileReader();
                                    r.onload = function(e) {
                                        xmldata = r.result;
                                    }
                                    r.readAsText(f);
                                } else {
                                    xmldata = null;
                                }
                            })

                            $("#campaign_delete_button").unbind("click").click(function(e){
                                e.preventDefault();

                                // test for existing responses
                                if(count && !confirm("This campaign has " + count + " responses. Are you sure?")){
                                    return;
                                }

                                var btn = $(this).attr("disabled", "disabled");
                                oh.campaign.delete({campaign_urn:urn}).done(function(){
                                    $('#myModal').modal("hide");
                                    tr.hide("slow", function(){
                                        alert("Campaign " + urn + " deleted!")
                                    });
                                }).always(function(){
                                    btn.removeAttr("disabled");
                                });
                            });

                            $("#campaign_save_button").unbind("click").click(function(e){
                                e.preventDefault();
                                var btn = $(this).attr("disabled", "disabled");
                                var running_state = $("#campaign_running")[0].checked ? "running" : "stopped";
                                var privacy_state = $("#campaign_privacy")[0].checked ? "shared" : "private";
                                var args = {
                                    campaign_urn : urn,
                                    running_state : running_state,
                                    privacy_state : privacy_state,
                                    description : $("#campaign_description").val(),
                                    class_list_remove : longdata.classes,
                                    class_list_add : $("#campaign_class").val()
                                }

                                //update xml only if selected
                                if(xmldata){
                                    args.xml = fixxml(xmldata, longdata.name ,urn);
                                }

                                oh.campaign.update(args).done(function(){
                                    td3.text(running_state);
                                    $('#myModal').modal("hide")
                                }).always(function(){
                                    btn.removeAttr("disabled");
                                });
                            });
                        });
                    }

                    // Disable for current deployment because confusing?
                    //a3.hide()
                    //a4.hide()
                    //a5.hide()

                    return oh.survey.count(urn).done(function(counts){
                        if(!Object.keys(counts).length){
                            //no existing responses found
                            count = 0;
                        } else {
                            count = $.map(counts, function(val, key) {
                                return val[0].count;
                            }).reduce(function(previousValue, currentValue) {
                                return previousValue + currentValue;
                            });
                        }
                        td4.text(count);
                    }).always(function(){
                        updateProgress((progress++/total) * 75 + 25);
                    });
                }
            });

            //data tables widget
            function initTable(){
                $('#campaigntable').dataTable( {
                    "dom" : '<"pull-right"l><"pull-left"f>tip',
                    "lengthMenu": [[25, 50, 100, -1], [25, 50, 100, "All"]],
                    "aoColumnDefs": [
                       { 'bSortable': false, 'aTargets': [ 0 ] }
                    ]
                });
            }

            //init temporary datatable
            initTable()

            //reinit final datatable after counts have been updated
            $.when.apply($, requests).always(function() {
                $("#progressdiv").addClass("hidden");
                $('#campaigntable').dataTable().fnDestroy();
                initTable();
            });

            //resetters
            $("#myModal").on("hidden.bs.modal", function(){
                $(".xml-upload-form").show();
                //$(".fileinput").fileinput("clear");
            })
        });

        //get users
        oh.user.read().done(function(x){
            $.each(Object.keys(x).sort(), function( i, name ) {
                //$("#campaign_author").append($("<option />").text(name));
            });
        });

        //get classes
        oh.class.read().done(function(x){
            $.each(Object.keys(x).sort(), function( i, urn ) {
                $("#campaign_class").append($("<option />").text(urn).attr("value", urn));
            });
        });
    });

    updateProgress = _.throttle(function(pct){
        $(".progress-bar").css("width", + pct + "%");
    }, 300);

    function message(msg, type){
        // type must be one of success, info, warning, danger
        type = type || "danger"
        $("#errordiv").empty().append('
×' + msg + '
');
        $('html, body').animate({
           scrollTop: 100
        }, 200);
    }

    //XML parser for mixed case tag names (HTML only supports lowercase tags)
    var parse = (function(parser, jQuery){
        return function(str) {
            return jQuery(parser.parseFromString(str, "text/xml").documentElement)
        }
    })(new DOMParser(), jQuery)

    function fixxml(input, name, urn){
        var xml = $.parseXML(input);
        var campaign = $("campaign", xml);
        campaign.children("campaignName").remove();
        campaign.children("campaignUrn").remove();
        campaign.prepend(parse("<campaignName/>").text(name))
        campaign.prepend(parse("<campaignUrn/>").text(urn))
        return (new XMLSerializer()).serializeToString(xml);
    }

})();
<|endoftext|>


<commit_before>/* ****** MODEL ******** */

var neighborhoodSpots = [
		{
			title: "Saggio",
			phone: "212-795-3080",
			location: {lat: 40.851473, lng: -73.939588},
			type: "Restaurant",
//			label: "Restaurant"
		},
    	{
    		title: "Mambi Steakhouse",
    		phone: "212-928-9796",
    		location: {lat: 40.84772, lng: -73.938251},
    		type: "Restaurant"
    	},
    	{
    		title: "Planet Fitness",
    		phone: "646-216-3150",
    		location: {lat: 40.847326, lng: -73.937638},
    		type: "Gym",
    //		label:"Gym"
    	},
    	{
    		title: "Le Cheile",
    		phone: "212-740-3111",
    		location: {lat: 40.851495, lng: -73.939988},
    		type: "Restaurant"
    	},
    	{
    		title: "Elite Cleaners",
    		phone: "212-927-5872",
    		location: {lat: 40.843097, lng: -73.939438},
    		type: "Dry Cleaners",
    //		label: "Dry Cleaners"
    	},
    	{
    		title: "Columbia Wine Co",
    		phone: "212-543-2633",
    		location: {lat: 40.842125, lng: -73.939272},
    		type: "Liquor Store",
    //		label: "Liquor Store"
    	}
	]

	//****** VIEW ******** //

var listView = function(data) {
	this.title = ko.observable(data.title);
	this.location = ko.observable(data.location);
	this.type = ko.observable(data.type);
}

// ****** VIEWMODEL ******** //

var ViewModel = function() {
	var self = this;

	this.places = ko.observableArray([]);

	neighborhoodSpots.forEach(function(locationItem) {
		self.places.push(new listView(locationItem));
	});

	this.selectedType = ko.observable();
	this.clearFilter = function() {
		this.selectedType(null)
	}
}

ko.applyBindings(new ViewModel());

// ******** MAP ******** //

var map;

// Create empty arry to push markers into.
var markers = [];

// Get that map going in the map div!
// Thanks to Google Maps API for the super helpful documentation, course, and instructions!
var initMap = function() {
	map = new google.maps.Map(document.getElementById('map'), {
		center: {lat: 40.843436, lng: -73.934794},
		zoom: 14
	});

	// Close infowindow when any other portion of the map is clicked.
	google.maps.event.addListener(map, "click", function(event) {
		mapInfoWindow.close();
	});

	var mapInfoWindow = new google.maps.InfoWindow();

	var defaultIcon = makeMarkerIcon('ff2d00');

	var highlightedIcon = makeMarkerIcon('631504');

	// loop through neighborhoodSpots array to make markers.
	for (var i = 0; i < neighborhoodSpots.length; i++) {
		var title = neighborhoodSpots[i].title;
		var phone = neighborhoodSpots[i].phone;
		var position = neighborhoodSpots[i].location;

		var marker = new google.maps.Marker({
			map: map,
			position: position,
			title: title,
			phone: phone,
			animation: google.maps.Animation.DROP,
			icon: defaultIcon,
			id: i
		});

	// Push markers to markers[] array.
	markers.push(marker);

	//Open info window on click.
	marker.addListener("click", function() {
		fillInfoWindow(this, mapInfoWindow);
	});

	// Change marker color when mouse hovers over marker.
	marker.addListener("mouseover", function() {
		this.setIcon(highlightedIcon);
	});

	// Use default color when not hovering over marker.
	marker.addListener("mouseout", function() {
		this.setIcon(defaultIcon);
	});
	}

function fillInfoWindow(marker, infowindow) {
	// Check if marker's window is already open.
	if (infowindow.marker != marker) {
		// Clear infowindow
		infowindow.setContent('');
		infowindow.marker = marker;
		// Open  infowinow
		infowindow.open(map, marker)

		// Close infowindow on click
		infowindow.addListener('closeclick', function() {
			infowindow.marker(null);
		});

		infowindow.setContent("
" + marker.title + "

" + marker.phone + "
")

	}
}

		// This function takes in a color, and then creates a new marker
       // icon of that color. The icon will be 21px wide by 34px high, have an
      // origin of 0, 0 and be anchored at 10, 34. Again, thank you Google API for the help.
      function makeMarkerIcon(markerColor) {
        var markerImage = new google.maps.MarkerImage(
          "https://chart.googleapis.com/chart?chst=d_map_spin&chld=1.15|0|" + markerColor +
          "|40|_|%E2%80%A2",
          new google.maps.Size(21, 34),
          new google.maps.Point(0, 0),
          new google.maps.Point(10, 34),
          new google.maps.Size(21,34));
        return markerImage;
      }

};<commit_msg>make marker bounce when toggled<commit_after>/* ****** MODEL ******** */

var neighborhoodSpots = [
		{
			title: "Saggio",
			phone: "212-795-3080",
			location: {lat: 40.851473, lng: -73.939588},
			type: "Restaurant",
//			label: "Restaurant"
		},
    	{
    		title: "Mambi Steakhouse",
    		phone: "212-928-9796",
    		location: {lat: 40.84772, lng: -73.938251},
    		type: "Restaurant"
    	},
    	{
    		title: "Planet Fitness",
    		phone: "646-216-3150",
    		location: {lat: 40.847326, lng: -73.937638},
    		type: "Gym",
    //		label:"Gym"
    	},
    	{
    		title: "Le Cheile",
    		phone: "212-740-3111",
    		location: {lat: 40.851495, lng: -73.939988},
    		type: "Restaurant"
    	},
    	{
    		title: "Elite Cleaners",
    		phone: "212-927-5872",
    		location: {lat: 40.843097, lng: -73.939438},
    		type: "Dry Cleaners",
    //		label: "Dry Cleaners"
    	},
    	{
    		title: "Columbia Wine Co",
    		phone: "212-543-2633",
    		location: {lat: 40.842125, lng: -73.939272},
    		type: "Liquor Store",
    //		label: "Liquor Store"
    	}
	]

	//****** VIEW ******** //

var listView = function(data) {
	this.title = ko.observable(data.title);
	this.location = ko.observable(data.location);
	this.type = ko.observable(data.type);
}

// ****** VIEWMODEL ******** //

var ViewModel = function() {
	var self = this;

	this.places = ko.observableArray([]);

	neighborhoodSpots.forEach(function(locationItem) {
		self.places.push(new listView(locationItem));
	});

	this.selectedType = ko.observable();
	this.clearFilter = function() {
		this.selectedType(null)
	}
}

ko.applyBindings(new ViewModel());

// ******** MAP ******** //

var map;

// Create empty arry to push markers into.
var markers = [];

// Get that map going in the map div!
// Thanks to Google Maps API for the super helpful documentation, course, and instructions!
var initMap = function() {
	map = new google.maps.Map(document.getElementById('map'), {
		center: {lat: 40.843436, lng: -73.934794},
		zoom: 14
	});

	// Close infowindow when any other portion of the map is clicked.
	google.maps.event.addListener(map, "click", function(event) {
		mapInfoWindow.close();
	});

	var mapInfoWindow = new google.maps.InfoWindow();

	var defaultIcon = makeMarkerIcon('ff2d00');

	var highlightedIcon = makeMarkerIcon('631504');

	// loop through neighborhoodSpots array to make markers.
	for (var i = 0; i < neighborhoodSpots.length; i++) {
		var title = neighborhoodSpots[i].title;
		var phone = neighborhoodSpots[i].phone;
		var position = neighborhoodSpots[i].location;

		var marker = new google.maps.Marker({
			map: map,
			position: position,
			title: title,
			phone: phone,
			// markers drop in when page loads.
			animation: google.maps.Animation.DROP,
			icon: defaultIcon,
			id: i
		});

	// Push markers to markers[] array.
	markers.push(marker);

	// Make marker bounce on click.
	marker.addListener("click", toggleBounce);

	//Open info window on click.
	marker.addListener("click", function() {
		fillInfoWindow(this, mapInfoWindow);
	});

	// Change marker color when mouse hovers over marker.
	marker.addListener("mouseover", function() {
		this.setIcon(highlightedIcon);
	});

	// Use default color when not hovering over marker.
	marker.addListener("mouseout", function() {
		this.setIcon(defaultIcon);
	});
	}

	function toggleBounce() {
		if (marker.getAnimation() !== null) {
			marker.setAnimation(null);
		} else {
			marker.setAnimation(google.maps.Animation.BOUNCE);
		}
	}

	function fillInfoWindow(marker, infowindow) {
		// Check if marker's window is already open.
		if (infowindow.marker != marker) {
			// Clear infowindow
			infowindow.setContent('');
			infowindow.marker = marker;
			// Open  infowinow
			infowindow.open(map, marker)

			// Close infowindow on click
			infowindow.addListener('closeclick', function() {
				infowindow.marker(null);
			});

			infowindow.setContent("
" + marker.title + "

" + marker.phone + "
")

			}
		}

		// This function takes in a color, and then creates a new marker
        // icon of that color. The icon will be 21px wide by 34px high, have an
        // origin of 0, 0 and be anchored at 10, 34. Again, thank you Google API for the help.
      function makeMarkerIcon(markerColor) {
        var markerImage = new google.maps.MarkerImage(
          "https://chart.googleapis.com/chart?chst=d_map_spin&chld=1.15|0|" + markerColor +
          "|40|_|%E2%80%A2",
          new google.maps.Size(21, 34),
          new google.maps.Point(0, 0),
          new google.maps.Point(10, 34),
          new google.maps.Size(21,34));
        return markerImage;
      }

};<|endoftext|>