<commit_before>const canvas = document.getElementById("gamecanvas");
const context = canvas.getContext("2d");

// keyboard events
var keys = [];
document.body.addEventListener("keydown", function (e) {
    keys[e.keyCode] = true;
});
document.body.addEventListener("keyup", function (e) {
    keys[e.keyCode] = false;
});

// touchscreen events
var touch = "";
document.addEventListener("touchstart", touchStartHandler);
document.addEventListener("touchend", touchEndHandler);
function touchStartHandler(e) {
    if(e.touches) {
        if (e.touches[0].pageX < canvas.offsetLeft + canvas.width/2) {
            touch = "left";
        } else {
            touch = "right";
        }
        e.preventDefault();
    }
}
function touchEndHandler(e) {
    if(e.touches) {
        touch = "";
        e.preventDefault();
    }
}

function sound(src) {
    this.sound = document.createElement("audio");
    this.sound.src = src;
    this.sound.setAttribute("preload", "auto");
    this.sound.setAttribute("controls", "none");
    this.sound.style.display = "none";
    document.body.appendChild(this.sound);
    this.play = function(){
        this.sound.play();
    }
    this.stop = function(){
        this.sound.pause();
    }
}

class Game {
    constructor(canvas) {
        this.canvas = canvas;

        this.sound = {};
        this.initializeSounds();

        this.startAttractMode();

        this.accumulator = 0;
        this.step = 1/360;
        let lastTime = null;
        this._frameCallback = (timestamp) => {
            if (lastTime !== null) {
                this.accumulator += (timestamp - lastTime) / 1000;
                while (this.accumulator >= this.step) {
                    this.processInput();
                    this.simulate(this.step);
                    this.accumulator -= this.step;
                }
                this.render();
            }
            lastTime = timestamp;
            requestAnimationFrame(this._frameCallback);
        };
        requestAnimationFrame(this._frameCallback);
    }

    startAttractMode() {
        this.attractMode = true;
        this.score = 0;
        this.multiplier = 1;
        this.lives = 1;
        this.level = Math.floor(Math.random() * 3) + 1;

        this.ball = new Ball();
        this.player = new Player();
        this.blocks = generateLevel(this.level);
    }

    startGame() {
        this.attractMode = false;
        this.score = 0;
        this.multiplier = 1;
        this.lives = 3;
        this.level = 1;

        this.ball = new Ball();
        this.player = new Player();
        this.blocks = generateLevel(this.level);
    }

    initializeSounds() {
        this.sound["PlayerHit"] = new sound("sounds/playerhit.wav");
        this.sound["BlockHit"] = new sound("sounds/blockhit.mp3");
        this.sound["WallHit"] = new sound("sounds/wallhit.wav");
        this.sound["LifeLost"] = new sound("sounds/lifelost.mp3");
    }

    processInput() {
        if ((keys[37] || touch == "left") && !this.attractMode) {
            this.player.moveLeft();
        }
        if ((keys[39] || touch == "right") && !this.attractMode) {
            this.player.moveRight();
        }
        if ((keys[13] || touch != "") && this.attractMode) {
            this.startGame();
            this.ball = new Ball();
            this.player = new Player();
        }
        if (keys[27] && !this.attractMode) {
            this.startAttractMode();
        }
    }

    simulate(deltaTime) {
        this.player.update(deltaTime);

        if (this.ball.pos.y-this.ball.height/2 > this.canvas.height) {
            // player missed the ball
            this.sound["LifeLost"].play();
            this.ball = new Ball();
            this.player = new Player();
            this.multiplier = 1;
            if (--this.lives == 0) this.startAttractMode(); // fix me
        } else if (this.ball.pos.y-this.ball.height/2 <= 0) {
            // ball touched ceiling
            this.sound["WallHit"].play();
            this.ball.velocity.y = -this.ball.velocity.y;
        } else if (this.ball.pos.x-this.ball.width/2 <= 0 || this.ball.pos.x+this.ball.width/2 >= this.canvas.width) {
            // ball touched left or right wall
            this.sound["WallHit"].play();
            this.ball.velocity.x = -this.ball.velocity.x;
        }
        this.ball.pos.x += this.ball.velocity.x * deltaTime;
        this.ball.pos.y += this.ball.velocity.y * deltaTime;

        // detect ball collision with player
        if (this.ball.collisionDetection(this.player)) {
            this.sound["PlayerHit"].play();
            this.ball.velocity.x = ((this.ball.pos.x+this.ball.width/2) - (this.player.pos.x+this.player.width/2)) * 6;
            this.ball.velocity.y = -this.ball.velocity.y;
            this.multiplier = 1;
        }

        // detect ball collision with blocks
        this.blocks.forEach((block)=> {
            if (this.ball.collisionDetection(block)) {
                this.sound["BlockHit"].play();
                this.score += this.multiplier++;

                var health = block.damage();
                if (health <= 0) {
                    var i = this.blocks.indexOf(block);
                    this.blocks.splice(i, 1);
                }

                var side = this.ball.collisionSide(block);
                if (side == "top/bottom") {
                    this.ball.velocity.y = -this.ball.velocity.y;
                } else {
                    this.ball.velocity.x = -this.ball.velocity.x;
                }
            }
        });

        // check if level cleared
        if (this.blocks.length == 0) {
            if (this.attractMode) {
                // restart attract mode
                this.startAttractMode();
            } else {
                // move to next level
                this.blocks = generateLevel(++this.level);
                this.ball = new Ball();
                this.player = new Player();
            }
        }

        // AI
        if (this.attractMode) {
            if (this.ball.pos.y > this.canvas.height*0.3 && this.ball.pos.y < this.canvas.height*0.9) {
                if ((this.player.pos.x + this.player.width/2) - (this.ball.pos.x + this.ball.width/2) < 50) {
                    this.player.moveRight();
                } else if ((this.player.pos.x + this.player.width/2) - (this.ball.pos.x + this.ball.width/2) > -50) {
                    this.player.moveLeft();
                }
            }
        }
    }

    render() {
        // draw background
        context.fillStyle = "#272822";
        context.fillRect(0, 0, canvas.width, canvas.height);

        // draw objects
        this.ball.draw();
        this.player.draw();
        this.blocks.forEach(function(block) {
            block.draw();
        });

        // draw text
        if (this.attractMode) {
            context.fillStyle = "rgba(0, 0, 0, 0.75)";
            context.fillRect(canvas.width/2-140, canvas.height*3/4-20, 280, 28);
            context.fillStyle = "white";
            context.font = "20px Georgia";
            context.textAlign = "center";
            context.fillText("Press <enter> to start playing", canvas.width / 2, canvas.height * 3/4);
        } else {
            context.fillStyle = "rgba(255, 255, 255, 0.75)";
            context.font = "20px Georgia";
            context.textAlign = "left";
            context.fillText("Score: " + this.score, 10, 20);
            context.textAlign = "center";
            context.fillText("Level: " + this.level, canvas.width/2, 20);
            context.textAlign = "right";
            context.fillText("Lives: " + this.lives, canvas.width-10, 20);
            context.globalAlpha = 1;
        }
    }
}

class Rectangle {
    constructor(x, y, width, height, color="#FFF") {
        this.pos = { x: x, y: y};
        this.width = width;
        this.height = height;
        this.color = color;
    }

    get left() {
        return this.pos.x;
    }

    get right() {
        return this.pos.x + this.width;
    }

    get top() {
        return this.pos.y;
    }

    get bottom() {
        return this.pos.y + this.height;
    }

    collisionDetection(object) {
        if (this.left < object.right &&
            this.right > object.left &&
            this.top < object.bottom &&
            this.bottom > object.top) {
            return true;
        }
        return false;
    }

    collisionSide(object) {
        // top/bottom or left/right
        if (this.right >= object.left && this.left <= object.right) {
            return "top/bottom";
        } else if (this.top >= object.bottom && this.bottom <= object.top) {
            return "left/right";
        }
        return "";
    }

    draw() {
        context.save();

        context.shadowBlur = 10;
        context.shadowColor = "black";
        context.fillStyle = this.color;
        context.fillRect(this.pos.x, this.pos.y, this.width, this.height);

        context.strokeStyle = "black";
        context.lineWidth = 1;
        context.strokeRect(this.pos.x+0.5, this.pos.y+0.5, this.width-1, this.height-1);

        context.restore();
    }
}

class Player extends Rectangle {
    constructor() {
        const width = 120;
        const height = 16;
        super(canvas.width / 2 - width/2, canvas.height - 32, width, height, "#F92672");
        this.velocity = 0;
        this.speed = 50;
        this.friction = 0.9;
    }

    moveLeft() {
        this.velocity -= this.speed;
    }

    moveRight() {
        this.velocity += this.speed;
    }

    update(deltaTime) {
        this.pos.x += this.velocity * deltaTime;
        this.velocity *= this.friction;

        if (this.pos.x+this.width/2 < 0) {
            this.pos.x = -this.width/2;
            this.velocity = 0;
        } else if (this.pos.x+this.width/2 > canvas.width) {
            this.pos.x = canvas.width-this.width/2;
            this.velocity = 0;
        }
    }
}

class Ball extends Rectangle {
    constructor() {
        const size = 12;
        super(canvas.width/2, canvas.height-64, size, size, "#F8F8F2");
        this.speed = -300;
        this.velocity = {x: (Math.random() + 0.5) * Math.pow(-1, Math.floor(Math.random() * 2)) * 60,
                         y: this.speed};
    }
}

class Block extends Rectangle {
    constructor(x, y, width, height, color="#FFE792", health=1) {
        super(x, y, width, height, color);
        this.health = health;
    }

    damage(d=1) {
        this.health -= d;
        return this.health;
    }

    draw() {
        super.draw();
        if (this.health > 1) {
            context.strokeStyle = "darkgray";
            context.lineWidth = 1;
            context.strokeRect(this.pos.x+2.5, this.pos.y+2.5, this.width-5, this.height-5);
        }
    }
}

function generateLevel(level) {
    const blocks = [];
    const colors = ["#F92672", "#66D9EF", "#A6E22E", "#FD971F", "#AE81FF", "#FFE792", "#FFE792"];
    if (level == 1) {
        for (row = 0; row < 7; row++) {
            for (col = 0; col < 8; col++) {
                blocks.push(new Block(2+col*60, 60+row*20, 58, 16, colors[row]));
            }
        }
    } else if (level == 2) {
        for (row = 0; row < 3; row++) {
            for (col = 1; col < 7; col++) {
                blocks.push(new Block(2+col*60, 60+row*20, 58, 16, colors[row]));
            }
        }

        for (row = 0; row < 4; row++) {
            for (col = 0; col < 8; col++) {
                if (col == 2 || col == 5) continue;
                blocks.push(new Block(2+col*60, 160+row*20, 58, 16, colors[row]));
            }
        }

        for (col = 0; col < 8; col++) {
            blocks.push(new Block(2+col*60, 160+row*20, 58, 16, "grey", 2));
        }
    } else if (level == 3) {
        blocks.push(new Block(60, 60, 16, 196, "grey", 2));
        blocks.push(new Block(canvas.width-76, 60, 16, 196, "grey", 2));

        for (row = 0; row < 3; row++) {
            for (col = 0; col < 6; col++) {
                blocks.push(new Block(80+col*54, 60+row*20, 50, 16, colors[row]));
            }
        }
        for (row = 0; row < 4; row++) {
            blocks.push(new Block(80, 120+row*20, 50, 16, colors[2]));
            blocks.push(new Block(canvas.width-130, 120+row*20, 50, 16, colors[2]));
        }

        for (col = 0; col < 2; col++) {
            blocks.push(new Block(134+col*108, 120, 104, 76, colors[5]));
        }

        for (row = 0; row < 3; row++) {
            for (col = 0; col < 6; col++) {
                blocks.push(new Block(80+col*54, 200+row*20, 50, 16, colors[2-row]));
            }
        }

        for (col = 0; col < 6; col++) {
            blocks.push(new Block(80+col*54, 200+row*20, 50, 16, "grey", 2));
        }
    } else {
        // simple random level
        for (row = 0; row < 7; row++) {
            for (col = 0; col < 8; col++) {
                if (Math.random() >= 0.5) continue;
                blocks.push(new Block(2+col*60, 60+row*20, 58, 16, colors[row]));
            }
        }
    }
    return blocks;
}

var game = new Game(canvas);
<commit_msg>Fixed incorrect collisionSide detection<commit_after>const canvas = document.getElementById("gamecanvas");
const context = canvas.getContext("2d");

// keyboard events
var keys = [];
document.body.addEventListener("keydown", function (e) {
    keys[e.keyCode] = true;
});
document.body.addEventListener("keyup", function (e) {
    keys[e.keyCode] = false;
});

// touchscreen events
var touch = "";
document.addEventListener("touchstart", touchStartHandler);
document.addEventListener("touchend", touchEndHandler);
function touchStartHandler(e) {
    if(e.touches) {
        if (e.touches[0].pageX < canvas.offsetLeft + canvas.width/2) {
            touch = "left";
        } else {
            touch = "right";
        }
        e.preventDefault();
    }
}
function touchEndHandler(e) {
    if(e.touches) {
        touch = "";
        e.preventDefault();
    }
}

function sound(src) {
    this.sound = document.createElement("audio");
    this.sound.src = src;
    this.sound.setAttribute("preload", "auto");
    this.sound.setAttribute("controls", "none");
    this.sound.style.display = "none";
    document.body.appendChild(this.sound);
    this.play = function(){
        this.sound.play();
    }
    this.stop = function(){
        this.sound.pause();
    }
}

class Game {
    constructor(canvas) {
        this.canvas = canvas;

        this.sound = {};
        this.initializeSounds();

        this.startAttractMode();

        this.accumulator = 0;
        this.step = 1/360;
        let lastTime = null;
        this._frameCallback = (timestamp) => {
            if (lastTime !== null) {
                this.accumulator += (timestamp - lastTime) / 1000;
                while (this.accumulator >= this.step) {
                    this.processInput();
                    this.simulate(this.step);
                    this.accumulator -= this.step;
                }
                this.render();
            }
            lastTime = timestamp;
            requestAnimationFrame(this._frameCallback);
        };
        requestAnimationFrame(this._frameCallback);
    }

    startAttractMode() {
        this.attractMode = true;
        this.score = 0;
        this.multiplier = 1;
        this.lives = 1;
        this.level = Math.floor(Math.random() * 3) + 1;

        this.ball = new Ball();
        this.player = new Player();
        this.blocks = generateLevel(this.level);
    }

    startGame() {
        this.attractMode = false;
        this.score = 0;
        this.multiplier = 1;
        this.lives = 3;
        this.level = 1;

        this.ball = new Ball();
        this.player = new Player();
        this.blocks = generateLevel(this.level);
    }

    initializeSounds() {
        this.sound["PlayerHit"] = new sound("sounds/playerhit.wav");
        this.sound["BlockHit"] = new sound("sounds/blockhit.mp3");
        this.sound["WallHit"] = new sound("sounds/wallhit.wav");
        this.sound["LifeLost"] = new sound("sounds/lifelost.mp3");
    }

    processInput() {
        if ((keys[37] || touch == "left") && !this.attractMode) {
            this.player.moveLeft();
        }
        if ((keys[39] || touch == "right") && !this.attractMode) {
            this.player.moveRight();
        }
        if ((keys[13] || touch != "") && this.attractMode) {
            this.startGame();
            this.ball = new Ball();
            this.player = new Player();
        }
        if (keys[27] && !this.attractMode) {
            this.startAttractMode();
        }
    }

    simulate(deltaTime) {
        this.player.update(deltaTime);

        if (this.ball.pos.y-this.ball.height/2 > this.canvas.height) {
            // player missed the ball
            this.sound["LifeLost"].play();
            this.ball = new Ball();
            this.player = new Player();
            this.multiplier = 1;
            if (--this.lives == 0) this.startAttractMode(); // fix me
        } else if (this.ball.pos.y-this.ball.height/2 <= 0) {
            // ball touched ceiling
            this.sound["WallHit"].play();
            this.ball.velocity.y = -this.ball.velocity.y;
        } else if (this.ball.pos.x-this.ball.width/2 <= 0 || this.ball.pos.x+this.ball.width/2 >= this.canvas.width) {
            // ball touched left or right wall
            this.sound["WallHit"].play();
            this.ball.velocity.x = -this.ball.velocity.x;
        }
        this.ball.pos.x += this.ball.velocity.x * deltaTime;
        this.ball.pos.y += this.ball.velocity.y * deltaTime;

        // detect ball collision with player
        if (this.ball.collisionDetection(this.player)) {
            this.sound["PlayerHit"].play();
            this.ball.velocity.x = ((this.ball.pos.x+this.ball.width/2) - (this.player.pos.x+this.player.width/2)) * 6;
            this.ball.velocity.y = -this.ball.velocity.y;
            this.multiplier = 1;
        }

        // detect ball collision with blocks
        this.blocks.forEach((block)=> {
            if (this.ball.collisionDetection(block)) {
                this.sound["BlockHit"].play();
                this.score += this.multiplier++;

                var health = block.damage();
                if (health <= 0) {
                    var i = this.blocks.indexOf(block);
                    this.blocks.splice(i, 1);
                }

                var side = this.ball.collisionSide(block);
                if (side == "top/bottom") {
                    this.ball.velocity.y = -this.ball.velocity.y;
                } else {
                    this.ball.velocity.x = -this.ball.velocity.x;
                }
            }
        });

        // check if level cleared
        if (this.blocks.length == 0) {
            if (this.attractMode) {
                // restart attract mode
                this.startAttractMode();
            } else {
                // move to next level
                this.blocks = generateLevel(++this.level);
                this.ball = new Ball();
                this.player = new Player();
            }
        }

        // AI
        if (this.attractMode) {
            if (this.ball.pos.y > this.canvas.height*0.3 && this.ball.pos.y < this.canvas.height*0.9) {
                if ((this.player.pos.x + this.player.width/2) - (this.ball.pos.x + this.ball.width/2) < 50) {
                    this.player.moveRight();
                } else if ((this.player.pos.x + this.player.width/2) - (this.ball.pos.x + this.ball.width/2) > -50) {
                    this.player.moveLeft();
                }
            }
        }
    }

    render() {
        // draw background
        context.fillStyle = "#272822";
        context.fillRect(0, 0, canvas.width, canvas.height);

        // draw objects
        this.ball.draw();
        this.player.draw();
        this.blocks.forEach(function(block) {
            block.draw();
        });

        // draw text
        if (this.attractMode) {
            context.fillStyle = "rgba(0, 0, 0, 0.75)";
            context.fillRect(canvas.width/2-140, canvas.height*3/4-20, 280, 28);
            context.fillStyle = "white";
            context.font = "20px Georgia";
            context.textAlign = "center";
            context.fillText("Press <enter> to start playing", canvas.width / 2, canvas.height * 3/4);
        } else {
            context.fillStyle = "rgba(255, 255, 255, 0.75)";
            context.font = "20px Georgia";
            context.textAlign = "left";
            context.fillText("Score: " + this.score, 10, 20);
            context.textAlign = "center";
            context.fillText("Level: " + this.level, canvas.width/2, 20);
            context.textAlign = "right";
            context.fillText("Lives: " + this.lives, canvas.width-10, 20);
            context.globalAlpha = 1;
        }
    }
}

class Rectangle {
    constructor(x, y, width, height, color="#FFF") {
        this.pos = { x: x, y: y};
        this.width = width;
        this.height = height;
        this.color = color;
    }

    get left() {
        return this.pos.x;
    }

    get right() {
        return this.pos.x + this.width;
    }

    get top() {
        return this.pos.y;
    }

    get bottom() {
        return this.pos.y + this.height;
    }

    collisionDetection(object) {
        if (this.left < object.right &&
            this.right > object.left &&
            this.top < object.bottom &&
            this.bottom > object.top) {
            return true;
        }
        return false;
    }

    collisionSide(object) {
        const intersectionVertical = this.height + object.height - Math.abs(this.top-object.top) - Math.abs(this.bottom-object.bottom);
        const intersectionHorizontal = this.width + object.width - Math.abs(this.left-object.left) - Math.abs(this.right-object.right);

        // top/bottom or left/right
        if (intersectionVertical <= intersectionHorizontal) {
            return "top/bottom";
        } else {
            return "left/right";
        }
        return "";
    }

    draw() {
        context.save();

        context.shadowBlur = 10;
        context.shadowColor = "black";
        context.fillStyle = this.color;
        context.fillRect(this.pos.x, this.pos.y, this.width, this.height);

        context.strokeStyle = "black";
        context.lineWidth = 1;
        context.strokeRect(this.pos.x+0.5, this.pos.y+0.5, this.width-1, this.height-1);

        context.restore();
    }
}

class Player extends Rectangle {
    constructor() {
        const width = 120;
        const height = 16;
        super(canvas.width / 2 - width/2, canvas.height - 32, width, height, "#F92672");
        this.velocity = 0;
        this.speed = 50;
        this.friction = 0.9;
    }

    moveLeft() {
        this.velocity -= this.speed;
    }

    moveRight() {
        this.velocity += this.speed;
    }

    update(deltaTime) {
        this.pos.x += this.velocity * deltaTime;
        this.velocity *= this.friction;

        if (this.pos.x+this.width/2 < 0) {
            this.pos.x = -this.width/2;
            this.velocity = 0;
        } else if (this.pos.x+this.width/2 > canvas.width) {
            this.pos.x = canvas.width-this.width/2;
            this.velocity = 0;
        }
    }
}

class Ball extends Rectangle {
    constructor() {
        const size = 12;
        super(canvas.width/2, canvas.height-64, size, size, "#F8F8F2");
        this.speed = -300;
        this.velocity = {x: (Math.random() + 0.5) * Math.pow(-1, Math.floor(Math.random() * 2)) * 60,
                         y: this.speed};
    }
}

class Block extends Rectangle {
    constructor(x, y, width, height, color="#FFE792", health=1) {
        super(x, y, width, height, color);
        this.health = health;
    }

    damage(d=1) {
        this.health -= d;
        return this.health;
    }

    draw() {
        super.draw();
        if (this.health > 1) {
            context.strokeStyle = "darkgray";
            context.lineWidth = 1;
            context.strokeRect(this.pos.x+2.5, this.pos.y+2.5, this.width-5, this.height-5);
        }
    }
}

function generateLevel(level) {
    const blocks = [];
    const colors = ["#F92672", "#66D9EF", "#A6E22E", "#FD971F", "#AE81FF", "#FFE792", "#FFE792"];
    if (level == 1) {
        for (row = 0; row < 7; row++) {
            for (col = 0; col < 8; col++) {
                blocks.push(new Block(2+col*60, 60+row*20, 58, 16, colors[row]));
            }
        }
    } else if (level == 2) {
        for (row = 0; row < 3; row++) {
            for (col = 1; col < 7; col++) {
                blocks.push(new Block(2+col*60, 60+row*20, 58, 16, colors[row]));
            }
        }

        for (row = 0; row < 4; row++) {
            for (col = 0; col < 8; col++) {
                if (col == 2 || col == 5) continue;
                blocks.push(new Block(2+col*60, 160+row*20, 58, 16, colors[row]));
            }
        }

        for (col = 0; col < 8; col++) {
            blocks.push(new Block(2+col*60, 160+row*20, 58, 16, "grey", 2));
        }
    } else if (level == 3) {
        blocks.push(new Block(60, 60, 16, 196, "grey", 2));
        blocks.push(new Block(canvas.width-76, 60, 16, 196, "grey", 2));

        for (row = 0; row < 3; row++) {
            for (col = 0; col < 6; col++) {
                blocks.push(new Block(80+col*54, 60+row*20, 50, 16, colors[row]));
            }
        }
        for (row = 0; row < 4; row++) {
            blocks.push(new Block(80, 120+row*20, 50, 16, colors[2]));
            blocks.push(new Block(canvas.width-130, 120+row*20, 50, 16, colors[2]));
        }

        for (col = 0; col < 2; col++) {
            blocks.push(new Block(134+col*108, 120, 104, 76, colors[5]));
        }

        for (row = 0; row < 3; row++) {
            for (col = 0; col < 6; col++) {
                blocks.push(new Block(80+col*54, 200+row*20, 50, 16, colors[2-row]));
            }
        }

        for (col = 0; col < 6; col++) {
            blocks.push(new Block(80+col*54, 200+row*20, 50, 16, "grey", 2));
        }
    } else {
        // simple random level
        for (row = 0; row < 7; row++) {
            for (col = 0; col < 8; col++) {
                if (Math.random() >= 0.5) continue;
                blocks.push(new Block(2+col*60, 60+row*20, 58, 16, colors[row]));
            }
        }
    }
    return blocks;
}

var game = new Game(canvas);
<|endoftext|>


<commit_before>'use strict';

/*!
 * Snakeskin
 * https://github.com/SnakeskinTpl/Snakeskin
 *
 * Released under the MIT license
 * https://github.com/SnakeskinTpl/Snakeskin/blob/master/LICENSE
 */

import Snakeskin from '../core';

Snakeskin.addDirective(
	'if',

	{
		block: true,
		group: 'if',
		notEmpty: true
	},

	function (command) {
		this.append($=> `if (${this.out(command, {sys: true})}) {`);
	},

	function () {
		this.append('}');
	}

);

Snakeskin.addDirective(
	'unless',

	{
		block: true,
		group: 'if',
		notEmpty: true
	},

	function (command) {
		this.append($=> `if (!(${this.out(command, {sys: true})})) {`);
	},

	function () {
		this.append('}');
	}

);

Snakeskin.addDirective(
	'else',

	{
		with: Snakeskin.group('if')
	},

	function (command) {
		if (command) {
			if (!this.isReady()) {
				return;
			}

			const
				parts = command.split(' '),
				prfx = parts[0] === 'unless' ? '!' : '';

			if (this.getGroup('if')[parts[0]]) {
				parts.shift();
			}

			this.append(`} else if (${prfx}(${this.out(parts.join(' '), {sys: true})})) {`);

		} else {
			this.append('} else {');
		}
	}

);

Snakeskin.addDirective(
	'switch',

	{
		block: true,
		children: Snakeskin.group('case'),
		notEmpty: true
	},

	function (command) {
		this.append($=> `switch (${this.out(command, {sys: true})}) {`);
	},

	function () {
		this.append('}');
	}

);

Snakeskin.addDirective(
	'case',

	{
		block: true,
		group: 'case',
		notEmpty: true,
		replacers: {'/>': 'end case', '>': 'case '}
	},

	function (command) {
		this.append($=> `case ${this.out(command, {sys: true})}: {`);
	},

	function () {
		this.append('} break;');
	}

);

Snakeskin.addDirective(
	'default',

	{
		block: true,
		group: 'case'
	},

	function () {
		this.append('default: {');
	},

	function () {
		this.append('}');
	}

);
<commit_msg>Refactoring<commit_after>'use strict';

/*!
 * Snakeskin
 * https://github.com/SnakeskinTpl/Snakeskin
 *
 * Released under the MIT license
 * https://github.com/SnakeskinTpl/Snakeskin/blob/master/LICENSE
 */

import Snakeskin from '../core';

Snakeskin.addDirective(
	'if',

	{
		block: true,
		group: ['if', 'logic'],
		notEmpty: true
	},

	function (command) {
		this.append($=> `if (${this.out(command, {sys: true})}) {`);
	},

	function () {
		this.append('}');
	}

);

Snakeskin.addDirective(
	'unless',

	{
		block: true,
		group: ['if', 'logic'],
		notEmpty: true
	},

	function (command) {
		this.append($=> `if (!(${this.out(command, {sys: true})})) {`);
	},

	function () {
		this.append('}');
	}

);

Snakeskin.addDirective(
	'else',

	{
		group: ['else', 'logic'],
		with: Snakeskin.group('if')
	},

	function (command) {
		// else if OR else unless
		if (command) {
			if (!this.isReady()) {
				return;
			}

			const
				parts = command.split(' '),
				prfx = parts[0] === 'unless' ? '!' : '';

			if (this.getGroup('if')[parts[0]]) {
				parts.shift();
			}

			this.append(`} else if (${prfx}(${this.out(parts.join(' '), {sys: true})})) {`);

		} else {
			this.append('} else {');
		}
	}

);

Snakeskin.addDirective(
	'switch',

	{
		block: true,
		children: Snakeskin.group('case'),
		group: ['switch', 'logic'],
		notEmpty: true
	},

	function (command) {
		this.append($=> `switch (${this.out(command, {sys: true})}) {`);
	},

	function () {
		this.append('}');
	}

);

Snakeskin.addDirective(
	'case',

	{
		block: true,
		group: ['case', 'logic'],
		notEmpty: true,
		replacers: {'/>': 'end case', '>': 'case '}
	},

	function (command) {
		this.append($=> `case ${this.out(command, {sys: true})}: {`);
	},

	function () {
		this.append('} break;');
	}

);

Snakeskin.addDirective(
	'default',

	{
		block: true,
		group: ['case', 'logic']
	},

	function () {
		this.append('default: {');
	},

	function () {
		this.append('}');
	}

);
<|endoftext|>


<commit_before>var tz = require('timezone');
var calcMealCOB = require('oref0/lib/determine-basal/cob-autosens');
var get_iob = require('oref0/lib/iob');
var isf = require('../profile/isf');

function diaCarbs(opts, time) {
    var treatments = opts.treatments;
    var profile_data = opts.profile;
    if (typeof(opts.glucose) !== 'undefined') {
        var glucose_data = opts.glucose;
    }
    var carbs = 0;
    var boluses = 0;
    var carbDelay = 20 * 60 * 1000;
    var maxCarbs = 0;
    var mealCarbTime = time.getTime();
    if (!treatments) return {};

    //console.error(glucose_data);
    var iob_inputs = {
        profile: profile_data
    ,   history: opts.pumphistory
    };
    var COB_inputs = {
        glucose_data: glucose_data
    ,   iob_inputs: iob_inputs
    ,   basalprofile: opts.basalprofile
    ,   mealTime: mealCarbTime
    };
    var mealCOB = 0;

    glucose_data.forEach(function(glucose_datum) {
        var bgTime = glucose_data.dateString.getTime();
        treatments.forEach(function(treatment) {
            var dia_ago = bgTime - 1.5*profile_data.dia*60*60*1000;
            var treatmentDate = new Date(tz(treatment.timestamp));
            var treatmentTime = treatmentDate.getTime();
            if (treatmentTime > dia_ago && treatmentTime <= bgTime) {
                if (treatment.carbs >= 1) {
                    console.error(treatment.carbs, maxCarbs, treatmentDate);
                    carbs += parseFloat(treatment.carbs);
                    COB_inputs.mealTime = treatmentTime;
                    var myCarbsAbsorbed = calcMealCOB(COB_inputs).carbsAbsorbed;
                    var myMealCOB = Math.max(0, carbs - myCarbsAbsorbed);
                    mealCOB = Math.max(mealCOB, myMealCOB);
                    console.error(mealCOB);
                }
                if (treatment.bolus >= 0.1) {
                    boluses += parseFloat(treatment.bolus);
                }
            }
        });
        if (mealCOB > 0) {
            csf_glucose_data.push(glucose_datum);
        }
        // Go through the remaining time periods and divide them into periods where scheduled basal insulin activity dominates. This would be determined by calculating the BG impact of scheduled basal insulin (for example 1U/hr * 48 mg/dL/U ISF = 48 mg/dL/hr = 5 mg/dL/5m), and comparing that to BGI from bolus and net basal insulin activity.
        var sens = isf.isfLookup(profile.isfProfile,bgTime);
        iob_inputs.clock=bgTime;
        currentBasal = basal.basalLookup(basalprofile, bgTime);
        iob_inputs.profile.current_basal = currentBasal;
        basalBgi = Math.round(( currentBasal * sens / 60 * 5 )*100)/100; // U/hr * mg/dL/U * 1 hr / 60 minutes * 5 = mg/dL/5m
        //console.log(JSON.stringify(iob_inputs.profile));
        var iob = get_iob(iob_inputs)[0];
        //console.log(JSON.stringify(iob));

        var bgi = Math.round(( -iob.activity * sens * 5 )*100)/100;
        if (basalBgi > bgi) {
            basal_glucose_data.push(glucose_datum);
        } else {
            isf_glucose_data.push(glucose_datum);
        }
    });

    return {
        csf_glucose_data: csf_glucose_data,
        isf_glucose_data: isf_glucose_data,
        basal_glucose_data: basal_glucose_data
    };
}

exports = module.exports = diaCarbs;

<commit_msg>debugging<commit_after>var tz = require('timezone');
var calcMealCOB = require('oref0/lib/determine-basal/cob-autosens');
var basal = require('oref0/lib/profile/basal');
var get_iob = require('oref0/lib/iob');
var isf = require('../profile/isf');

function diaCarbs(opts, time) {
    var treatments = opts.treatments;
    var profile_data = opts.profile;
    if (typeof(opts.glucose) !== 'undefined') {
        var glucose_data = opts.glucose;
    }
    var carbs = 0;
    var boluses = 0;
    var carbDelay = 20 * 60 * 1000;
    var maxCarbs = 0;
    var mealCarbTime = time.getTime();
    if (!treatments) return {};

    console.error(glucose_data);
    var iob_inputs = {
        profile: profile_data
    ,   history: opts.pumphistory
    };
    var COB_inputs = {
        glucose_data: glucose_data
    ,   iob_inputs: iob_inputs
    ,   basalprofile: opts.basalprofile
    ,   mealTime: mealCarbTime
    };
    var mealCOB = 0;
    var csf_glucose_data = [];
    var isf_glucose_data = [];
    var basal_glucose_data = [];

    glucose_data.forEach(function(glucose_datum) {
        var bgDate = new Date(tz(glucose_datum.dateString));
        var bgTime = bgDate.getTime();
        treatments.forEach(function(treatment) {
            var dia_ago = bgTime - 1.5*profile_data.dia*60*60*1000;
            var treatmentDate = new Date(tz(treatment.timestamp));
            var treatmentTime = treatmentDate.getTime();
            if (treatmentTime > dia_ago && treatmentTime <= bgTime) {
                if (treatment.carbs >= 1) {
                    console.error(treatment.carbs, maxCarbs, treatmentDate);
                    carbs += parseFloat(treatment.carbs);
                    COB_inputs.mealTime = treatmentTime;
                    var myCarbsAbsorbed = calcMealCOB(COB_inputs).carbsAbsorbed;
                    var myMealCOB = Math.max(0, carbs - myCarbsAbsorbed);
                    mealCOB = Math.max(mealCOB, myMealCOB);
                    console.error(mealCOB);
                }
                if (treatment.bolus >= 0.1) {
                    boluses += parseFloat(treatment.bolus);
                }
            }
        });
        if (mealCOB > 0) {
            csf_glucose_data.push(glucose_datum);
        }
        // Go through the remaining time periods and divide them into periods where scheduled basal insulin activity dominates. This would be determined by calculating the BG impact of scheduled basal insulin (for example 1U/hr * 48 mg/dL/U ISF = 48 mg/dL/hr = 5 mg/dL/5m), and comparing that to BGI from bolus and net basal insulin activity.
        var sens = isf.isfLookup(iob_inputs.profile.isfProfile,bgDate);
        iob_inputs.clock=bgTime;
        currentBasal = basal.basalLookup(opts.basalprofile, bgDate);
        iob_inputs.profile.current_basal = currentBasal;
        basalBgi = Math.round(( currentBasal * sens / 60 * 5 )*100)/100; // U/hr * mg/dL/U * 1 hr / 60 minutes * 5 = mg/dL/5m
        //console.log(JSON.stringify(iob_inputs.profile));
        var iob = get_iob(iob_inputs)[0];
        //console.log(JSON.stringify(iob));

        var bgi = Math.round(( -iob.activity * sens * 5 )*100)/100;
        if (basalBgi > bgi) {
            basal_glucose_data.push(glucose_datum);
        } else {
            isf_glucose_data.push(glucose_datum);
        }
    });

    return {
        csf_glucose_data: csf_glucose_data,
        isf_glucose_data: isf_glucose_data,
        basal_glucose_data: basal_glucose_data
    };
}

exports = module.exports = diaCarbs;

<|endoftext|>


<commit_before>// Copyright (c) 2013, Web Notes Technologies Pvt. Ltd.
// License: GNU General Public License v3. See license.txt

//

//--------- ONLOAD -------------
cur_frm.cscript.onload = function(doc, cdt, cdn) {

}

cur_frm.cscript.refresh = function(doc, cdt, cdn) {
   cur_frm.set_footnote(wn.markdown(cur_frm.meta.description));
}

cur_frm.pformat.purchase_tax_details= function(doc){

  //function to make row of table
  var make_row = function(title,val,bold){
    var bstart = ''; var bend = '';
    return '
'+(bold?bstart:'')+title+(bold?bend:'')+'	'
     +'	'
     +''+format_currency(val, doc.currency)+'	'
     +'
'
  }

  function convert_rate(val){
    var new_val = flt(val)/flt(doc.conversion_rate);
    return new_val;
  }

  var cl = getchildren('Purchase Taxes and Charges',doc.name,'purchase_tax_details');

  // outer table
  var out='

\

	';

  // main table
  out +='
'
  if(!print_hide('net_total')) {
	out += make_row('Net Total', convert_rate(doc.net_total), 1);
  }

  // add rows
  if(cl.length){
    for(var i=0;i<cl.length;i++){
      out += make_row(cl[i].description,convert_rate(cl[i].tax_amount),0);
    }
  }
	// grand total
	if(!print_hide('grand_total_import')) {
		out += make_row('Grand Total', doc.grand_total_import, 1);
	}
  if(doc.in_words_import && !print_hide('in_words_import')){
    out +='

';
    out += '
';
    out += '

In Words	';
    out+= ''+doc.in_words_import+'
';
  }
  out +='

';
  return out;
}

cur_frm.cscript.add_deduct_tax = function(doc, cdt, cdn) {
  var d = locals[cdt][cdn];
  if(!d.category && d.add_deduct_tax){
    alert("Please select Category first");
    d.add_deduct_tax = '';
  }
  else if(d.category != 'Total' && d.add_deduct_tax == 'Deduct') {
	console.log([d.category, d.add_deduct_tax]);
    msgprint("You cannot deduct when category is for 'Valuation' or 'Valuation and Total'");
    d.add_deduct_tax = '';
  }

}

cur_frm.cscript.charge_type = function(doc, cdt, cdn) {
  var d = locals[cdt][cdn];
  if(!d.category && d.charge_type){
    alert("Please select Category first");
    d.charge_type = '';
  }
  else if(d.idx == 1 && (d.charge_type == 'On Previous Row Amount' || d.charge_type == 'On Previous Row Total')){
    alert("You cannot select Charge Type as 'On Previous Row Amount' or 'On Previous Row Total' for first row");
    d.charge_type = '';
  }
  else if((d.category == 'Valuation' || d.category == 'Valuation and Total') && (d.charge_type == 'On Previous Row Amount' || d.charge_type == 'On Previous Row Total')){
    alert("You cannot select charge type as 'On Previous Row Amount' or 'On Previous Row Total' for valuation. You can select only 'Total' option for previous row amount or previous row total")
    d.charge_type = '';
  }
  validated = false;
  refresh_field('charge_type',d.name,'purchase_tax_details');

  cur_frm.cscript.row_id(doc, cdt, cdn);
  cur_frm.cscript.rate(doc, cdt, cdn);
  cur_frm.cscript.tax_amount(doc, cdt, cdn);
}

cur_frm.cscript.row_id = function(doc, cdt, cdn) {
  var d = locals[cdt][cdn];
  if(!d.charge_type && d.row_id){
    alert("Please select Charge Type first");
    d.row_id = '';
  }
  else if((d.charge_type == 'Actual' || d.charge_type == 'On Net Total') && d.row_id) {
    alert("You can Enter Row only if your Charge Type is 'On Previous Row Amount' or ' Previous Row Total'");
    d.row_id = '';
  }
  else if((d.charge_type == 'On Previous Row Amount' || d.charge_type == 'On Previous Row Total') && d.row_id){
    if(d.row_id >= d.idx){
      alert("You cannot Enter Row no. greater than or equal to current row no. for this Charge type");
      d.row_id = '';
    }
  }
  validated = false;
  refresh_field('row_id',d.name,'purchase_tax_details');
}

cur_frm.set_query("account_head", "purchase_tax_details", function(doc) {
	return {
		query: "controllers.queries.tax_account_query",
    	filters: {
			"account_type": ["Tax", "Chargeable", "Expense Account"],
			"debit_or_credit": "Debit",
			"company": doc.company
		}
	}
});

cur_frm.fields_dict['purchase_tax_details'].grid.get_field("cost_center").get_query = function(doc) {
  return {
    filters: {
      'company': doc.company,
      'group_or_ledger': "Ledger"
    }
  }
}

cur_frm.cscript.account_head = function(doc, cdt, cdn) {
  var d = locals[cdt][cdn];
  if(!d.charge_type && d.account_head){
    alert("Please select Charge Type first");
    validated = false;
    d.account_head = '';
  }
  else if(d.account_head && d.charge_type) {
    arg = "{'charge_type' : '" + d.charge_type + "', 'account_head' : '" + d.account_head + "'}";
    return get_server_fields('get_rate', arg, 'purchase_tax_details', doc, cdt, cdn, 1);
  }
  refresh_field('account_head',d.name,'purchase_tax_details');
}

cur_frm.cscript.rate = function(doc, cdt, cdn) {
  var d = locals[cdt][cdn];
  if(!d.charge_type && d.rate) {
    alert("Please select Charge Type first");
    d.rate = '';
  }
  validated = false;
  refresh_field('rate',d.name,'purchase_tax_details');
}

cur_frm.cscript.tax_amount = function(doc, cdt, cdn) {
  var d = locals[cdt][cdn];
  if(!d.charge_type && d.tax_amount){
    alert("Please select Charge Type first");
    d.tax_amount = '';
  }
  else if(d.charge_type && d.tax_amount) {
    alert("You cannot directly enter Amount and if your Charge Type is Actual enter your amount in Rate");
    d.tax_amount = '';
  }
  validated = false;
  refresh_field('tax_amount',d.name,'purchase_tax_details');
}
<commit_msg>[fix] [minor] check print hide properties in purchase standard print format<commit_after>// Copyright (c) 2013, Web Notes Technologies Pvt. Ltd.
// License: GNU General Public License v3. See license.txt

//

//--------- ONLOAD -------------
cur_frm.cscript.onload = function(doc, cdt, cdn) {

}

cur_frm.cscript.refresh = function(doc, cdt, cdn) {
   cur_frm.set_footnote(wn.markdown(cur_frm.meta.description));
}

cur_frm.pformat.purchase_tax_details= function(doc){

  //function to make row of table
  var make_row = function(title,val,bold){
    var bstart = ''; var bend = '';
    return '
'+(bold?bstart:'')+title+(bold?bend:'')+'	'
     +'	'
     +''+format_currency(val, doc.currency)+'	'
     +'
'
  }

  function convert_rate(val){
    var new_val = flt(val)/flt(doc.conversion_rate);
    return new_val;
  }

  function print_hide(fieldname) {
	var doc_field = wn.meta.get_docfield(doc.doctype, fieldname, doc.name);
	return doc_field.print_hide;
  }

  var cl = getchildren('Purchase Taxes and Charges',doc.name,'purchase_tax_details');

  // outer table
  var out='

\

	';

  // main table
  out +='
'
  if(!print_hide('net_total')) {
	out += make_row('Net Total', convert_rate(doc.net_total), 1);
  }

  // add rows
  if(cl.length){
    for(var i=0;i<cl.length;i++){
      out += make_row(cl[i].description,convert_rate(cl[i].tax_amount),0);
    }
  }
	// grand total
	if(!print_hide('grand_total_import')) {
		out += make_row('Grand Total', doc.grand_total_import, 1);
	}
  if(doc.in_words_import && !print_hide('in_words_import')){
    out +='

';
    out += '
';
    out += '

In Words	';
    out+= ''+doc.in_words_import+'
';
  }
  out +='

';
  return out;
}

cur_frm.cscript.add_deduct_tax = function(doc, cdt, cdn) {
  var d = locals[cdt][cdn];
  if(!d.category && d.add_deduct_tax){
    alert("Please select Category first");
    d.add_deduct_tax = '';
  }
  else if(d.category != 'Total' && d.add_deduct_tax == 'Deduct') {
	console.log([d.category, d.add_deduct_tax]);
    msgprint("You cannot deduct when category is for 'Valuation' or 'Valuation and Total'");
    d.add_deduct_tax = '';
  }

}

cur_frm.cscript.charge_type = function(doc, cdt, cdn) {
  var d = locals[cdt][cdn];
  if(!d.category && d.charge_type){
    alert("Please select Category first");
    d.charge_type = '';
  }
  else if(d.idx == 1 && (d.charge_type == 'On Previous Row Amount' || d.charge_type == 'On Previous Row Total')){
    alert("You cannot select Charge Type as 'On Previous Row Amount' or 'On Previous Row Total' for first row");
    d.charge_type = '';
  }
  else if((d.category == 'Valuation' || d.category == 'Valuation and Total') && (d.charge_type == 'On Previous Row Amount' || d.charge_type == 'On Previous Row Total')){
    alert("You cannot select charge type as 'On Previous Row Amount' or 'On Previous Row Total' for valuation. You can select only 'Total' option for previous row amount or previous row total")
    d.charge_type = '';
  }
  validated = false;
  refresh_field('charge_type',d.name,'purchase_tax_details');

  cur_frm.cscript.row_id(doc, cdt, cdn);
  cur_frm.cscript.rate(doc, cdt, cdn);
  cur_frm.cscript.tax_amount(doc, cdt, cdn);
}

cur_frm.cscript.row_id = function(doc, cdt, cdn) {
  var d = locals[cdt][cdn];
  if(!d.charge_type && d.row_id){
    alert("Please select Charge Type first");
    d.row_id = '';
  }
  else if((d.charge_type == 'Actual' || d.charge_type == 'On Net Total') && d.row_id) {
    alert("You can Enter Row only if your Charge Type is 'On Previous Row Amount' or ' Previous Row Total'");
    d.row_id = '';
  }
  else if((d.charge_type == 'On Previous Row Amount' || d.charge_type == 'On Previous Row Total') && d.row_id){
    if(d.row_id >= d.idx){
      alert("You cannot Enter Row no. greater than or equal to current row no. for this Charge type");
      d.row_id = '';
    }
  }
  validated = false;
  refresh_field('row_id',d.name,'purchase_tax_details');
}

cur_frm.set_query("account_head", "purchase_tax_details", function(doc) {
	return {
		query: "controllers.queries.tax_account_query",
    	filters: {
			"account_type": ["Tax", "Chargeable", "Expense Account"],
			"debit_or_credit": "Debit",
			"company": doc.company
		}
	}
});

cur_frm.fields_dict['purchase_tax_details'].grid.get_field("cost_center").get_query = function(doc) {
  return {
    filters: {
      'company': doc.company,
      'group_or_ledger': "Ledger"
    }
  }
}

cur_frm.cscript.account_head = function(doc, cdt, cdn) {
  var d = locals[cdt][cdn];
  if(!d.charge_type && d.account_head){
    alert("Please select Charge Type first");
    validated = false;
    d.account_head = '';
  }
  else if(d.account_head && d.charge_type) {
    arg = "{'charge_type' : '" + d.charge_type + "', 'account_head' : '" + d.account_head + "'}";
    return get_server_fields('get_rate', arg, 'purchase_tax_details', doc, cdt, cdn, 1);
  }
  refresh_field('account_head',d.name,'purchase_tax_details');
}

cur_frm.cscript.rate = function(doc, cdt, cdn) {
  var d = locals[cdt][cdn];
  if(!d.charge_type && d.rate) {
    alert("Please select Charge Type first");
    d.rate = '';
  }
  validated = false;
  refresh_field('rate',d.name,'purchase_tax_details');
}

cur_frm.cscript.tax_amount = function(doc, cdt, cdn) {
  var d = locals[cdt][cdn];
  if(!d.charge_type && d.tax_amount){
    alert("Please select Charge Type first");
    d.tax_amount = '';
  }
  else if(d.charge_type && d.tax_amount) {
    alert("You cannot directly enter Amount and if your Charge Type is Actual enter your amount in Rate");
    d.tax_amount = '';
  }
  validated = false;
  refresh_field('tax_amount',d.name,'purchase_tax_details');
}
<|endoftext|>


<commit_before>define(function (require, exports, module){
    var _ = require('../vendor/lodash.min'),
        target = $('body')[0],
        config = require('../config'),
        locale = require('./locale'),
        dialogId = '.extension-manager-dialog.modal',
        extensionService = require('./extensions'),
        downloadsTemplate = require('text!../templates/downloads.html'),
        selectTemplate = _.template(require('text!../templates/sortButton.html'),{
            sortby: locale.get('sortby'),
            author: locale.get('author'),
            downloads: locale.get('downloads'),
            update: locale.get('update'),
            name: locale.get('name')
        });

    function init(){
        var observer = new MutationObserver(function(mutations){
            mutations.forEach(function(mutation) {
                if (mutation.type === 'childList' && mutation.addedNodes && mutation.addedNodes.length === 1){
                    dialogAddedMutation(mutation);
                }
            });
        }),
            observerConfig = config.mutationObserverConfig;
        observer.observe(target, observerConfig);
    }

    function dialogAddedMutation(mutation){
        var waitForRegistry = true;

        function registryUpdateAction(){
            waitForRegistry = false;
        }

        extensionService.updateRegistry()
            .then(registryUpdateAction, registryUpdateAction);

        var target = $(mutation.addedNodes[0]),
            token;

        if (target.find(dialogId).length === 1){
            mutateSortButton(target);
            mutateTabButtons(target);

            token = setInterval(function(){
                var extensions = target.find('#registry tr, #installed tr'),
                    extensionCount = extensions.length;
                if (extensionCount < 200 || waitForRegistry){
                    return;
                }

                clearInterval(token);

                //extensionService.add(extensions);
                mutateExistingExtensions(extensions);
            }, 100);
        }
    }

    function mutateTabButtons(target){
        target.find('.nav-tabs li').click(function(){
            returnPanelToNorm();
        });
    }

    function mutateExistingExtensions(targets){
        if (targets.length === 0) return;

        $('#registry, #installed').click(function(event){
            var $t = $(event.target),
                $parent = $(event.currentTarget);

            if ($t.attr('class') === 'ext-link_more'){
                var id = $t.attr('data-extension-id'),
                    extension = extensionService.get(id);

                if ($parent.find('.ext-panel_more').length > 0){
                    $parent.find('.ext-panel_more').remove();
                    returnPanelToNorm();
                } else {
                    $parent.find('tr').hide();
                    var insert = createMorePanelContent(id, extension, $parent);
                    $parent.find('tr[data-extension-id="' + id + '"]')
                        .show()
                        .after(insert);
                }
            }
        });

        _.each(targets, function(target){
            var $t = $(target),
                id = $t.find('[data-extension-id]').attr('data-extension-id'),
                extension = extensionService.get(id),
                totalDownloads = extension && extension.totalDownloads? extension.totalDownloads : 0;

            $t.attr('data-extension-id', id);

            $t.find('.ext-info').append(_.template(downloadsTemplate, {
                downloads: totalDownloads,
                str_downloads: locale.get('downloads'),
                str_more: locale.get('more'),
                id: id
            }));
            $t.attr('data-extension-loads', totalDownloads);
        });
    }

    function returnPanelToNorm(parent){
        $('.ext-panel_more').remove();
        if (parent){
            parent.find('tr').show();
        } else {
            $('#registry tr, #installed tr').show();
        }
    }

    function daysBetween(first, second) {
        var one = new Date(first.getFullYear(), first.getMonth(), first.getDate());
        var two = new Date(second.getFullYear(), second.getMonth(), second.getDate());

        var millisecondsPerDay = 1000 * 60 * 60 * 24;
        var millisBetween = two.getTime() - one.getTime();
        var days = millisBetween / millisecondsPerDay;

        return Math.abs(Math.ceil(days));
    }

    function createMorePanelContent(id, extension, parent){
        var panel = $('

'),
            holder = $('	'),
            hide = $(_.template('<button class="btn primary">${str_hide}</button>	', {
                str_hide: locale.get('hide')
            }));

        panel.append(holder);

        if (_.isArray(extension.versions)){
            var versions = extension.versions.slice().reverse(),
                showLines = 3;

            if (extension.totalDownloads){
                var maxDate = new Date(versions[0].published),
                    minDate = new Date(versions[versions.length - 1].published),
                    diffDays = daysBetween(maxDate, minDate) || 1;

                holder.append(_.template(locale.get('statusTemplate'), {
                    days: diffDays,
                    dpd: (extension.totalDownloads / diffDays).toFixed(0)
                }));
            }

            _.each(versions, function(info, index){
                holder.append(_.template(locale.get('versionTemplate'),{
                    version: info.version,
                    date: new Date(info.published).toLocaleDateString(),
                    downloads: info.downloads || 0
                }));
                if (index >= showLines - 1 && versions.length > showLines) {
                    var count = versions.length - (showLines - 1);
                    if (count === 1) {
                        holder.append(locale.get('oneMoreVersion'));
                    } else {
                        holder.append(_.template(locale.get('moreVersionsTemplate'),{ count : count }));
                    }
                    return false;
                }
            });
        }

        hide.click(function(){
            returnPanelToNorm(parent);
        });

        panel.append(hide);

        return panel;
    }

    function mutateSortButton(target){
        var $header = target.find('.modal-header'),
            $select = $(selectTemplate);

        $select.on('change', function(event){
            if (typeof this.value === 'string'){
                sort(this.value);
            }
        });
        $header.append($select);
    }

    var sortHandlers = {
        'downloads': function(elements){
            return elements = _.sortBy(elements, function(el){
                return -parseInt($(el).attr('data-extension-loads'));
            });
        },
        'author': function(elements){
            return _.sortBy(elements, function(el){
                return $(el).find('.ext-author a').text();
            });
        },
        'name': function(elements){
            return _.sortBy(elements, function(el){
                return $(el).find('.ext-author').text();
            });
        },
        'update': function(elements){
            return _.sortBy(elements, function(el){
                return - new Date($(el).find('.ext-date').text().replace(' - ', ''));
            });
        }
    }

    function sort(criteria){
        var handler = sortHandlers[criteria],
            holder = $(dialogId).find('.extension-list.active tbody'),
            elements = holder.find('tr');

        if (typeof handler !== 'function'){ return; }

        holder.empty();
        elements = handler(elements);
        holder.append(elements);
    }

    exports.init = init;
});
<commit_msg>downloads per day fix<commit_after>define(function (require, exports, module){
    var _ = require('../vendor/lodash.min'),
        target = $('body')[0],
        config = require('../config'),
        locale = require('./locale'),
        dialogId = '.extension-manager-dialog.modal',
        extensionService = require('./extensions'),
        downloadsTemplate = require('text!../templates/downloads.html'),
        selectTemplate = _.template(require('text!../templates/sortButton.html'),{
            sortby: locale.get('sortby'),
            author: locale.get('author'),
            downloads: locale.get('downloads'),
            update: locale.get('update'),
            name: locale.get('name')
        });

    function init(){
        var observer = new MutationObserver(function(mutations){
            mutations.forEach(function(mutation) {
                if (mutation.type === 'childList' && mutation.addedNodes && mutation.addedNodes.length === 1){
                    dialogAddedMutation(mutation);
                }
            });
        }),
            observerConfig = config.mutationObserverConfig;
        observer.observe(target, observerConfig);
    }

    function dialogAddedMutation(mutation){
        var waitForRegistry = true;

        function registryUpdateAction(){
            waitForRegistry = false;
        }

        extensionService.updateRegistry()
            .then(registryUpdateAction, registryUpdateAction);

        var target = $(mutation.addedNodes[0]),
            token;

        if (target.find(dialogId).length === 1){
            mutateSortButton(target);
            mutateTabButtons(target);

            token = setInterval(function(){
                var extensions = target.find('#registry tr, #installed tr'),
                    extensionCount = extensions.length;
                if (extensionCount < 200 || waitForRegistry){
                    return;
                }

                clearInterval(token);

                //extensionService.add(extensions);
                mutateExistingExtensions(extensions);
            }, 100);
        }
    }

    function mutateTabButtons(target){
        target.find('.nav-tabs li').click(function(){
            returnPanelToNorm();
        });
    }

    function mutateExistingExtensions(targets){
        if (targets.length === 0) return;

        $('#registry, #installed').click(function(event){
            var $t = $(event.target),
                $parent = $(event.currentTarget);

            if ($t.attr('class') === 'ext-link_more'){
                var id = $t.attr('data-extension-id'),
                    extension = extensionService.get(id);

                if ($parent.find('.ext-panel_more').length > 0){
                    $parent.find('.ext-panel_more').remove();
                    returnPanelToNorm();
                } else {
                    $parent.find('tr').hide();
                    var insert = createMorePanelContent(id, extension, $parent);
                    $parent.find('tr[data-extension-id="' + id + '"]')
                        .show()
                        .after(insert);
                }
            }
        });

        _.each(targets, function(target){
            var $t = $(target),
                id = $t.find('[data-extension-id]').attr('data-extension-id'),
                extension = extensionService.get(id),
                totalDownloads = extension && extension.totalDownloads? extension.totalDownloads : 0;

            $t.attr('data-extension-id', id);

            $t.find('.ext-info').append(_.template(downloadsTemplate, {
                downloads: totalDownloads,
                str_downloads: locale.get('downloads'),
                str_more: locale.get('more'),
                id: id
            }));
            $t.attr('data-extension-loads', totalDownloads);
        });
    }

    function returnPanelToNorm(parent){
        $('.ext-panel_more').remove();
        if (parent){
            parent.find('tr').show();
        } else {
            $('#registry tr, #installed tr').show();
        }
    }

    function daysBetween(first, second) {
        var one = new Date(first.getFullYear(), first.getMonth(), first.getDate());
        var two = new Date(second.getFullYear(), second.getMonth(), second.getDate());

        var millisecondsPerDay = 1000 * 60 * 60 * 24;
        var millisBetween = two.getTime() - one.getTime();
        var days = millisBetween / millisecondsPerDay;

        return Math.abs(Math.ceil(days));
    }

    function createMorePanelContent(id, extension, parent){
        var panel = $('

'),
            holder = $('	'),
            hide = $(_.template('<button class="btn primary">${str_hide}</button>	', {
                str_hide: locale.get('hide')
            }));

        panel.append(holder);

        if (_.isArray(extension.versions)){
            var versions = extension.versions.slice().reverse(),
                showLines = 3;

            if (extension.totalDownloads){
                var maxDate = new Date(),
                    minDate = new Date(versions[versions.length - 1].published),
                    diffDays = daysBetween(maxDate, minDate) || 1;

                holder.append(_.template(locale.get('statusTemplate'), {
                    days: diffDays,
                    dpd: (extension.totalDownloads / diffDays).toFixed(0)
                }));
            }

            _.each(versions, function(info, index){
                holder.append(_.template(locale.get('versionTemplate'),{
                    version: info.version,
                    date: new Date(info.published).toLocaleDateString(),
                    downloads: info.downloads || 0
                }));
                if (index >= showLines - 1 && versions.length > showLines) {
                    var count = versions.length - (showLines - 1);
                    if (count === 1) {
                        holder.append(locale.get('oneMoreVersion'));
                    } else {
                        holder.append(_.template(locale.get('moreVersionsTemplate'),{ count : count }));
                    }
                    return false;
                }
            });
        }

        hide.click(function(){
            returnPanelToNorm(parent);
        });

        panel.append(hide);

        return panel;
    }

    function mutateSortButton(target){
        var $header = target.find('.modal-header'),
            $select = $(selectTemplate);

        $select.on('change', function(event){
            if (typeof this.value === 'string'){
                sort(this.value);
            }
        });
        $header.append($select);
    }

    var sortHandlers = {
        'downloads': function(elements){
            return elements = _.sortBy(elements, function(el){
                return -parseInt($(el).attr('data-extension-loads'));
            });
        },
        'author': function(elements){
            return _.sortBy(elements, function(el){
                return $(el).find('.ext-author a').text();
            });
        },
        'name': function(elements){
            return _.sortBy(elements, function(el){
                return $(el).find('.ext-author').text();
            });
        },
        'update': function(elements){
            return _.sortBy(elements, function(el){
                return - new Date($(el).find('.ext-date').text().replace(' - ', ''));
            });
        }
    }

    function sort(criteria){
        var handler = sortHandlers[criteria],
            holder = $(dialogId).find('.extension-list.active tbody'),
            elements = holder.find('tr');

        if (typeof handler !== 'function'){ return; }

        holder.empty();
        elements = handler(elements);
        holder.append(elements);
    }

    exports.init = init;
});
<|endoftext|>


<commit_before>define(function (require, exports, module) {
    var Marionette = require('marionette'),
        Backbone = require('backbone'),
        DishesCollection = require('dishesCollection'),
        DaysMenuCollection = require('daysMenuCollection'),
        WeekModel = require('weekModel'),
        UserModel = require ('userModel'),
        MainLayoutView = require('mainLayoutView'),

        MainDashboardView = require('mainDashboardView'),
        MenuDaysController = require('menuDaysController'),

        MenuMainView = require('menuPreselectionView'),
        UserOrdersCollection = require('userOrdersCollection'),
        UserOrderModel = require('userOrderModel'),
        baseUrl = require('baseUrl'),
        weeksResource = require('weeksResource'),
        daysResource = require('daysResource'),
        ordersResource = require('ordersResource'),
        DayMenuSelectionView = require('dayMenuSelectionView');

    module.exports = Marionette.Object.extend({

        regions: new Marionette.RegionManager({
            regions: {
                'main': '#application',
                'content': '.js-content'
            }
        }),

        initialize: function () {
            this.getActiveUser();
            this.mainLayoutView = new MainLayoutView({model: this.activeUser});
            this.regions.get('main').show(this.mainLayoutView);

        },

        getActiveUser: function(){
            //564c7c59cd0f210f00887524-admin   564c7cafcd0f210f00887527-user
            this.activeUser = new UserModel({_id:'564c91c3694f9b0f006a66ca',
                                             firstName:'Admin',
                                             lastName:'Admin',
                                             image_path:'images/male.jpg',
                                             mail:'Admin@engagepoint.com',
                                             __v:0,
                                             role:'admin'});

            this.userId = this.activeUser.get('_id');

           /*
            var res = $.Deferred();
            this.activeUser = new UserModel();
            this.activeUser.setActiveUserUrl();
            $.when(
                this.activeUser.fetch()
            ).done(function () {
            this.userId = this.activeUser.get('_id');
                    res.resolve();
                }.bind(this));

            return res.promise();*/
        },

        getCurrentWeek: function () {
            var res = $.Deferred();

            this.currentWeekModel = new WeekModel();
            this.currentWeekModel.setCurrentWeekUrl();

            $.when(
                this.currentWeekModel.fetch()
            ).done(function () {
                    res.resolve();
                }.bind(this));

            return res.promise();
        },

        getNextWeek: function () {
            var res = $.Deferred();

            this.nextWeekModel = new WeekModel();
            this.nextWeekModel.setNextWeekUrl();

            $.when(
                this.nextWeekModel.fetch()
            ).done(function () {
                    res.resolve();
                }.bind(this));

            return res.promise();
        },

        getDays: function () {
            var res = $.Deferred();
            this.daysMenuCollection = new DaysMenuCollection();
            this.daysMenuCollection.setUrl(this.nextWeekModel);

            $.when(
                this.daysMenuCollection.fetch()
            ).done(function () {
                    res.resolve();
                }.bind(this));

            return res.promise();
        },

        preloadCurrentWeekData: function () {
            this.getCurrentWeek().done(function () {
                if(this.currentWeekModel.get('startDate') === undefined) {
                    //todo: error when week doesn't exist
                }
                else {
                    this.getDays().done(function () {
                        if(this.daysMenuCollection.length>0)
                            this.prepareOrders(this.currentWeekModel);
                        else
                        {
                            //todo: error when days don't exist
                        }
                    }.bind(this));
                }
            }.bind(this));
        },

        preloadNextWeekData: function () {
            this.getNextWeek().done(function () {
                if(this.nextWeekModel.get('startDate') === undefined) {
                    //todo: error when week doesn't exist
                }
                else {
                    this.getDays().done(function () {
                        if(this.daysMenuCollection.length>0)
                            this.prepareOrders(this.nextWeekModel);
                        else
                        {
                            //todo: error when days don't exist
                        }
                    }.bind(this));
                }
            }.bind(this));
        },

        getOrders: function (weekModel) {
            var res = $.Deferred();
            this.userOrdersCollection = new UserOrdersCollection();
            this.userOrdersCollection.setUrl(weekModel, this.userId);
            //debugger;

            $.when(
                this.userOrdersCollection.fetch()
            ).done(function () {
                    res.resolve();
                }.bind(this));

            return res.promise();
        },

        setOrders: function () {
            var res = $.Deferred();
            this.userOrdersCollection = new UserOrdersCollection();
            var index = 0;
            var days = this.nextWeekModel.get('days');
            for(index = 0; index < 5; index++) {
                this.userOrdersCollection.add(new UserOrderModel({
                    'userId': this.userId,
                    'paymentStatus': false,
                    'day': days[index],
                    'dishes': []
                }));
            }
            console.log(this.userOrdersCollection);
            this.userOrdersCollection.map(function (model) {
                model.setPostUrl();

                //model.setPutUrl();
                model.save();
                //model.destroy();
            });

        },

        prepareOrders: function (weekModel) {
            this.getOrders(weekModel).done(function () {
                console.log(this.userOrdersCollection);
                if(this.userOrdersCollection.length>0) {
                    this.startMenu();
                }
                else {
                    this.setOrders();
                    this.startMenu();
                }
            }.bind(this));
        },

        startMenu: function () {
                this.menuMainView = new MenuMainView();

                this.regions.get('content').show( this.menuMainView );
                this.currentDate = this.userOrdersCollection.at(0).restDate;
            debugger;
                this.dayDishesCollection = new DishesCollection(this.userOrdersCollection.at(0).get('dishes'));

                this.dayMenuSelectionView = new DayMenuSelectionView({model:new Backbone.Model({
                    summary: this.dayDishesCollection.calculateSummary()}),
                    collection: this.dayDishesCollection
                });
                this.currentDay = this.dayDishesCollection;
                //this.menuPreselectionView.showChildView('selectedUserMenu', this.dayMenuSelectionView);

                //this.daysMenuCollection.comparator = 'day';
            /*this.daysMenuCollection.map(function (model) {
                model.setRestDate();
            });*/
                //this.daysMenuCollection.sort();
            /*this.daysMenuCollection.map(function (model) {
                model.setVisibleDate();
            });*/
                this.tabContainer = new MenuDaysController({collection: this.daysMenuCollection});

                this.generatedMenu = this.tabContainer.getUserItem(this.userOrdersCollection);

                //this.menuCard.setSelectedMenu(this.dayMenuSelectionView);
                this.menuMainView.showChildView('dayMenu', this.generatedMenu);

                this.tabContainer.setSelectedMenu(this.dayMenuSelectionView);
                //user:day:menu:saved
                this.listenTo(this.dayMenuSelectionView, 'user:day:menu:saved', this.dayMenuSaved);
                this.listenTo(this.tabContainer, 'dish:added', this.dishAdded);
                this.listenTo(this.tabContainer, 'tab:changed', this.tabChanged);
        },

        dayMenuSaved: function (collection) {
            //todo: save user menu
            //debugger;
            this.currentDay.models[0].set('dishes', collection.toJSON());
            var date = new Date(this.currentDay.get('day'));
            //this.currentDay.setRestDate();
            //this.currentDay.setPutUrl(this.userId, this.currentDay.get('day'));
            console.log(this.currentDay);
            console.log(this.currentDay.url);
            //debugger;
            //this.currentDay.save();
            var filtered = this.userOrdersCollection.filter(function (userDayMenu) {
                return userDayMenu.restDate === this.currentDate;
            }.bind(this));
            debugger;
            filtered[0].setRestDate();
            filtered[0].setPutUrl(this.userId, this.currentDay.get('day'));
            //filtered[0].set('paymentStatus', true);
            var json = filtered[0].toJSON();
            debugger;
            /*var json = {
                "_id": filtered[0].get('_id'),

                "day": filtered[0].get('day'),
                "userId": this.userId,
                "paymentStatus": true,
                "dishes": [
                    {
                        "dish": {"_id":"5644bed76164be0f00634a94"},
                        "quantity": 4
                    },
                    {
                        "dish":{"_id":"56447473dff2e80f007e4fff"},
                        "quantity": 1
                    }
                ]

            };*/
            //debugger;
            $.ajax({
                url: this.currentDay.url,
                type: 'put',
                crossDomain: true,
                data: json,
                success: function(data) {
                    console.log('ok');
                    console.log(data);
                }.bind(this)
            });

            this.currentDay.setVisibleDate();
            console.log(this.currentDay);

            //save to rest
        },

        getDefaultMenuSelectionModel: function () {
            return new Backbone.Model({summary: 0});
        },

        menu: function () {
            this.preloadNextWeekData();
        },

        nextWeekDashboard: function () {

            this.getNextWeek().done(function () {
                this.getOrders(this.nextWeekModel);
                this.userOrdersCollection.state = 'next_week';
                this.nextMenuDashboard = new MainDashboardView({collection: this.userOrdersCollection});
                this.regions.get('content').show(this.nextMenuDashboard);
            }.bind(this));

        },

        dashboard: function () {
            this.getCurrentWeek().done(function () {
                this.getOrders(this.currentWeekModel);
                this.userOrdersCollection.state = 'current_week';
                this.dashboard = new MainDashboardView({collection: this.userOrdersCollection});
                this.regions.get('content').show(this.dashboard);
            }.bind(this));

        },

        dishAdded: function (model) {
            var dishInList = false;
            this.dayDishesCollection.map(function (dish) {
                if(dish.get('dish')._id === model.get('_id'))
                    dishInList = true;
            });
            if(!dishInList)
            {
                this.dayDishesCollection.add({dish: model.toJSON(), quantity: 1});
                console.log(this.dayDishesCollection.calculateSummary());
                this.dayMenuSelectionView.model = new Backbone.Model({summary: this.dayDishesCollection.calculateSummary()});
                this.dayMenuSelectionView.render();
            }
        },

        tabChanged: function (date) {
            console.log(date);
            this.selectDay(date);
        },

        selectDay: function (date) {
            this.currentDate = date;
            var filtered = this.userOrdersCollection.filter(function (userDayMenu) {
                return userDayMenu.get('day') === date;
            });
            this.dayDishesCollection = new DishesCollection(filtered[0].get('dishes'));
            this.currentDay = filtered[0];

            this.dayMenuSelectionView = new DayMenuSelectionView({model: new Backbone.Model({summary: this.dayDishesCollection.calculateSummary()}),
                collection: this.dayDishesCollection});

            this.tabContainer.setSelectedMenu(this.dayMenuSelectionView);
            this.listenTo(this.dayMenuSelectionView, 'user:day:menu:saved', this.dayMenuSaved);
        },

        index: function () {
            console.log('index route');
                console.log(this.userDaysMenuCollection);
        }

    });
});<commit_msg>almost stable manu<commit_after>define(function (require, exports, module) {
    var Marionette = require('marionette'),
        Backbone = require('backbone'),
        DishesCollection = require('dishesCollection'),
        DaysMenuCollection = require('daysMenuCollection'),
        WeekModel = require('weekModel'),
        UserModel = require ('userModel'),
        MainLayoutView = require('mainLayoutView'),

        MainDashboardView = require('mainDashboardView'),
        MenuDaysController = require('menuDaysController'),

        MenuMainView = require('menuPreselectionView'),
        UserOrdersCollection = require('userOrdersCollection'),
        UserOrderModel = require('userOrderModel'),
        baseUrl = require('baseUrl'),
        weeksResource = require('weeksResource'),
        daysResource = require('daysResource'),
        ordersResource = require('ordersResource'),
        DayMenuSelectionView = require('dayMenuSelectionView');

    module.exports = Marionette.Object.extend({

        regions: new Marionette.RegionManager({
            regions: {
                'main': '#application',
                'content': '.js-content'
            }
        }),

        initialize: function () {
            this.getActiveUser();
            this.mainLayoutView = new MainLayoutView({model: this.activeUser});
            this.regions.get('main').show(this.mainLayoutView);

        },

        getActiveUser: function(){
            //564c7c59cd0f210f00887524-admin   564c7cafcd0f210f00887527-user
            this.activeUser = new UserModel({_id:'564c91c3694f9b0f006a66ca',
                                             firstName:'Admin',
                                             lastName:'Admin',
                                             image_path:'images/male.jpg',
                                             mail:'Admin@engagepoint.com',
                                             __v:0,
                                             role:'admin'});

            this.userId = this.activeUser.get('_id');

           /*
            var res = $.Deferred();
            this.activeUser = new UserModel();
            this.activeUser.setActiveUserUrl();
            $.when(
                this.activeUser.fetch()
            ).done(function () {
            this.userId = this.activeUser.get('_id');
                    res.resolve();
                }.bind(this));

            return res.promise();*/
        },

        getCurrentWeek: function () {
            var res = $.Deferred();

            this.currentWeekModel = new WeekModel();
            this.currentWeekModel.setCurrentWeekUrl();

            $.when(
                this.currentWeekModel.fetch()
            ).done(function () {
                    res.resolve();
                }.bind(this));

            return res.promise();
        },

        getNextWeek: function () {
            var res = $.Deferred();

            this.nextWeekModel = new WeekModel();
            this.nextWeekModel.setNextWeekUrl();

            $.when(
                this.nextWeekModel.fetch()
            ).done(function () {
                    res.resolve();
                }.bind(this));

            return res.promise();
        },

        getDays: function () {
            var res = $.Deferred();
            this.daysMenuCollection = new DaysMenuCollection();
            this.daysMenuCollection.setUrl(this.nextWeekModel);

            $.when(
                this.daysMenuCollection.fetch()
            ).done(function () {
                    res.resolve();
                }.bind(this));

            return res.promise();
        },

        preloadCurrentWeekData: function () {
            this.getCurrentWeek().done(function () {
                if(this.currentWeekModel.get('startDate') === undefined) {
                    //todo: error when week doesn't exist
                }
                else {
                    this.getDays().done(function () {
                        if(this.daysMenuCollection.length>0)
                            this.prepareOrders(this.currentWeekModel);
                        else
                        {
                            //todo: error when days don't exist
                        }
                    }.bind(this));
                }
            }.bind(this));
        },

        preloadNextWeekData: function () {
            this.getNextWeek().done(function () {
                if(this.nextWeekModel.get('startDate') === undefined) {
                    //todo: error when week doesn't exist
                }
                else {
                    this.getDays().done(function () {
                        if(this.daysMenuCollection.length>0)
                            this.prepareOrders(this.nextWeekModel);
                        else
                        {
                            //todo: error when days don't exist
                        }
                    }.bind(this));
                }
            }.bind(this));
        },

        getOrders: function (weekModel) {
            var res = $.Deferred();
            this.userOrdersCollection = new UserOrdersCollection();
            this.userOrdersCollection.setUrl(weekModel, this.userId);
            //debugger;

            $.when(
                this.userOrdersCollection.fetch()
            ).done(function () {
                    res.resolve();
                }.bind(this));

            return res.promise();
        },

        setOrders: function () {
            var res = $.Deferred();
            this.userOrdersCollection = new UserOrdersCollection();
            var index = 0;
            var days = this.nextWeekModel.get('days');
            for(index = 0; index < 5; index++) {
                this.userOrdersCollection.add(new UserOrderModel({
                    'userId': this.userId,
                    'paymentStatus': false,
                    'day': days[index],
                    'dishes': []
                }));
            }
            console.log(this.userOrdersCollection);
            this.userOrdersCollection.map(function (model) {
                model.setPostUrl();

                //model.setPutUrl();
                model.save();
                //model.destroy();
            });

        },

        prepareOrders: function (weekModel) {
            this.getOrders(weekModel).done(function () {
                console.log(this.userOrdersCollection);
                if(this.userOrdersCollection.length>0) {
                    this.startMenu();
                }
                else {
                    this.setOrders();
                    this.startMenu();
                }
            }.bind(this));
        },

        startMenu: function () {
                this.menuMainView = new MenuMainView();

                this.regions.get('content').show( this.menuMainView );
                this.currentDate = this.userOrdersCollection.at(0).restDate;
            debugger;
                this.dayDishesCollection = new DishesCollection(this.userOrdersCollection.at(0).get('dishes'));

                this.dayMenuSelectionView = new DayMenuSelectionView({model:new Backbone.Model({
                    summary: this.dayDishesCollection.calculateSummary()}),
                    collection: this.dayDishesCollection
                });

                this.currentDay = this.userOrdersCollection.at(0);
                //this.menuPreselectionView.showChildView('selectedUserMenu', this.dayMenuSelectionView);

                //this.daysMenuCollection.comparator = 'day';
            /*this.daysMenuCollection.map(function (model) {
                model.setRestDate();
            });*/
                //this.daysMenuCollection.sort();
            /*this.daysMenuCollection.map(function (model) {
                model.setVisibleDate();
            });*/
                this.tabContainer = new MenuDaysController({collection: this.daysMenuCollection});

                this.generatedMenu = this.tabContainer.getUserItem(this.userOrdersCollection);

                //this.menuCard.setSelectedMenu(this.dayMenuSelectionView);
                this.menuMainView.showChildView('dayMenu', this.generatedMenu);

                this.tabContainer.setSelectedMenu(this.dayMenuSelectionView);
                //user:day:menu:saved
                this.listenTo(this.dayMenuSelectionView, 'user:day:menu:saved', this.dayMenuSaved);
                this.listenTo(this.tabContainer, 'dish:added', this.dishAdded);
                this.listenTo(this.tabContainer, 'tab:changed', this.tabChanged);
        },

        dayMenuSaved: function (collection) {
            //todo: save user menu
            //debugger;
            this.currentDay.set('dishes', collection.toJSON());
            var date = new Date(this.currentDay.get('day'));
            //this.currentDay.setRestDate();
            //this.currentDay.setPutUrl(this.userId, this.currentDay.get('day'));
            console.log(this.currentDay);
            console.log(this.currentDay.url);
            //debugger;
            //this.currentDay.save();
            var filtered = this.userOrdersCollection.filter(function (userDayMenu) {
                return userDayMenu.restDate === this.currentDay.restDate;
            }.bind(this));
            debugger;
            filtered[0].setRestDate();
            filtered[0].setPutUrl(this.userId, this.currentDay.get('day'));
            //filtered[0].set('paymentStatus', true);
            var json = filtered[0].toJSON();
            console.log(json);
            debugger;
            /*var json = {
                "_id": filtered[0].get('_id'),

                "day": filtered[0].get('day'),
                "userId": this.userId,
                "paymentStatus": true,
                "dishes": [
                    {
                        "dish": {"_id":"5644bed76164be0f00634a94"},
                        "quantity": 4
                    },
                    {
                        "dish":{"_id":"56447473dff2e80f007e4fff"},
                        "quantity": 1
                    }
                ]

            };*/
            //debugger;
            $.ajax({
                url: this.currentDay.url,
                type: 'put',
                crossDomain: true,
                data: json,
                success: function(data) {
                    console.log('ok');
                    console.log(data);
                }.bind(this)
            });

            this.currentDay.setVisibleDate();
            console.log(this.currentDay);

            //save to rest
        },

        getDefaultMenuSelectionModel: function () {
            return new Backbone.Model({summary: 0});
        },

        menu: function () {
            this.preloadNextWeekData();
        },

        nextWeekDashboard: function () {

            this.getNextWeek().done(function () {
                this.getOrders(this.nextWeekModel);
                this.userOrdersCollection.state = 'next_week';
                this.nextMenuDashboard = new MainDashboardView({collection: this.userOrdersCollection});
                this.regions.get('content').show(this.nextMenuDashboard);
            }.bind(this));

        },

        dashboard: function () {
            this.getCurrentWeek().done(function () {
                this.getOrders(this.currentWeekModel);
                this.userOrdersCollection.state = 'current_week';
                this.dashboard = new MainDashboardView({collection: this.userOrdersCollection});
                this.regions.get('content').show(this.dashboard);
            }.bind(this));

        },

        dishAdded: function (model) {
            var dishInList = false;
            this.dayDishesCollection.map(function (dish) {
                if(dish.get('dish')._id === model.get('_id'))
                    dishInList = true;
            });
            if(!dishInList)
            {
                this.dayDishesCollection.add({dish: model.toJSON(), quantity: 1});
                console.log(this.dayDishesCollection.calculateSummary());
                this.dayMenuSelectionView.model = new Backbone.Model({summary: this.dayDishesCollection.calculateSummary()});
                this.dayMenuSelectionView.render();
            }
        },

        tabChanged: function (date) {
            console.log(date);
            this.selectDay(date);
        },

        selectDay: function (date) {
            this.currentDate = date;
            var filtered = this.userOrdersCollection.filter(function (userDayMenu) {
                return userDayMenu.get('day') === date;
            });
            this.dayDishesCollection = new DishesCollection(filtered[0].get('dishes'));
            this.currentDay = filtered[0];

            this.dayMenuSelectionView = new DayMenuSelectionView({model: new Backbone.Model({summary: this.dayDishesCollection.calculateSummary()}),
                collection: this.dayDishesCollection});

            this.tabContainer.setSelectedMenu(this.dayMenuSelectionView);
            this.listenTo(this.dayMenuSelectionView, 'user:day:menu:saved', this.dayMenuSaved);
        },

        index: function () {
            console.log('index route');
                console.log(this.userDaysMenuCollection);
        }

    });
});<|endoftext|>