'use strict';

var http = require('http');
var fs = require('fs');

var hiscoresUrl = 'http://services.runescape.com/m=hiscore_oldschool/index_lite.ws?player=';

var playerName = 'Max Deviant';

http.get(hiscoresUrl + playerName, function (res) {
    var data = [];

    res.on('data', function (chunk) {
        data.push(chunk);
    });

    res.on('end', function () {
        var stats = extractStats(data.join().split('\n'));

        fs.readFile('quests.json', 'utf8', function (err, data) {
            if (err) {
                console.log(err);

                return;
            }

            var questList = JSON.parse(data);

            var tracker = new Quests(questList, stats);

            tracker.completeQuests(['death-plateau', 'troll-stronghold']);

            console.log(tracker.getCompleted());
        });
    });
}).end();

function extractStats(raw) {
    var stats = {};

    var skills = [
        'overall',
        'attack',
        'defence',
        'strength',
        'constitution',
        'ranged',
        'prayer',
        'magic',
        'cooking',
        'woodcutting',
        'fletching',
        'fishing',
        'firemaking',
        'crafting',
        'smithing',
        'mining',
        'herblore',
        'agility',
        'thieving',
        'slayer',
        'farming',
        'runecrafting',
        'hunter',
        'construction'
    ];

    for (var i in skills) {
        var row = raw[i].split(',');

        stats[skills[i]] = {
            rank: row[0],
            level: row[1],
            xp: row[2]
        };
    }

    return stats;
}

function grep (array, key, value) {
    for (var i in array) {
        if (array[i][key] === value) {
            return array[i];
        }
    }
};

var Quests = function (questList, stats) {
    this.list = questList;
    this.stats = stats;
    this.completed = {
        count: 0,
        percent: 0,
        list: {}
    };

    this.findQuest = function (questName) {
        return grep(this.list, 'slug', questName) || grep(this.list, 'name', questName);
    };

    this.findAvailable = function () {
        var available = [];

        for (var i in this.list) {
            var canDo = true;
            var skillReqs = this.list[i].requirements.skills;
            var questReqs = this.list[i].requirements.quests;

            if (this.completed.list[this.list[i].slug]) {
                continue;
            }

            if (this.hasRequirements(this.list[i].slug)) {
                available.push(this.list[i].slug);
            }
        }

        return available;
    };

    this.listRequirements = function (questName) {
        var quest = this.findQuest(questName);

        return quest.requirements;
    };

    this.hasRequirements = function (questName) {
        var hasStats = true;
        var hasQuests = true;

        var quest = this.findQuest(questName);

        var skillReqs = quest.requirements.skills;
        var questReqs = quest.requirements.quests;

        for (var i in skillReqs) {
            if (this.stats[i].level < skillReqs[i]) {
                hasStats = false;
            }
        }

        for (var i in questReqs) {
            if (!this.completed.list[questReqs[i]]) {
                hasQuests = false;
            }
        }

        return hasStats && hasQuests;
    };

    this.completeQuest = function (quest) {
        this.completeQuests([quest]);
    };

    this.completeQuests = function (quests) {
        for (var i in quests) {
            this.completed.list[quests[i]] = true;
            this.completed.count++;
        }
    };

    this.getCompleted = function () {
        return {
            count: this.completed.count,
            percent: Math.round((this.completed.count / this.list.length) * 100),
            quests: Object.keys(this.completed.list)
        };
    };
};

@@ -804,21 +804,48 @@
 ker.
-getCompleted(
+computeTotalRequirements('legends-quest'
 ));%0A
@@ -3903,12 +3903,1195 @@
 ;%0A    %7D;
+%0A%0A    this.computeTotalRequirements = function (questName) %7B%0A        var quest = this.findQuest(questName);%0A%0A        var skillReqs = quest.requirements.skills;%0A        var questReqs = quest.requirements.quests;%0A%0A        var totalSkills = %7B%7D;%0A        var totalQuests = %5B%5D;%0A%0A        for (var i in skillReqs) %7B%0A            totalSkills%5Bi%5D = skillReqs%5Bi%5D;%0A        %7D%0A%0A        for (var i in questReqs) %7B%0A            var priorReqs = this.computeTotalRequirements(questReqs%5Bi%5D);%0A%0A            for (var j in priorReqs) %7B%0A                if (typeof totalSkills%5Bj%5D === 'undefined') %7B%0A                    totalSkills%5Bj%5D = priorReqs%5Bj%5D;%0A                %7D else if (priorReqs%5Bj%5D %3E totalSkills%5Bj%5D) %7B%0A                    totalSkills%5Bj%5D = priorReqs%5Bj%5D;%0A                %7D%0A            %7D%0A        %7D%0A%0A        return totalSkills;%0A    %7D;%0A%0A    this.recommendNext = function () %7B%0A        var recommended = %5B%5D;%0A%0A        for (var i in this.list) %7B%0A            if (this.completed.list%5Bthis.list%5Bi%5D%5D) %7B%0A                continue;%0A            %7D%0A%0A            if (!this.hasRequirements(this.list%5Bi%5D.slug)) %7B%0A                recommended.push(this.list%5Bi%5D.slug);%0A            %7D%0A        %7D%0A%0A        return recommended;%0A    %7D;
 %0A%7D;%0A

Add method to compute total skill requirements for a quest