# graphics/text.js

    'use strict';

    var Thing = require('./thing.js');

    /**
     * @class Text
     * @augments Thing
     * @param {string} label - The words of the text.
     * @param {string} font - String of the desired font of the text.
     */
    var Text = function(label, font) {
        Thing.call(this);
        this.label = label;
        this.type = 'Text';

        this.font = font == undefined ? '20pt Arial' : font;

        // Text needs a graphics context for computing height and width
        // we set this by default on running any graphics program, but
        // then it can get over-written the first time we call draw.
        this.context = null;

        this.resetDimensions();
    }

    Text.prototype = new Thing();
    Text.prototype.constructor = Text;

    Text.defaultContext = null;

    /**
     * Define a default context for the text.
     * Text objects need access to some 2d graphics context to compute
     * height and width. This might be done before a draw call.
     * @param {CodeHSGraphics} __graphics__ - Instance of the graphics module.
     */
    Text.giveDefaultContext = function(__graphics__){
        Text.defaultContext = __graphics__.getContext();
    }

    /**
     * Reset the dimensions of the text to the size in the context.
     */
    Text.prototype.resetDimensions = function(){
        var context = this.context || Text.defaultContext;
        context.font = this.font;
        this.width = context.measureText(this.label).width;
        this.height = context.measureText('m').width * 1.2; /* No height provided */
    }

    /**
     * Draw the text in the current context.
     * @param {CodeHSGraphics} __graphics__ - Instance of the graphics module.
     */
    Text.prototype.draw = function(__graphics__){
        var context = __graphics__.getContext();
        this.context = context;
        context.fillStyle = this.color.toString();
        context.beginPath();
        context.font = this.font;
        this.resetDimensions();
        context.fillText(this.label, this.x,this.y);
        context.closePath();
        context.fill();
    }

    /**
     * Set the font of the text.
     * Re-calculates the dimensions of the font after font change.
     * @param {string} font - String of the desired font for the text.
     */
    Text.prototype.setFont = function(font){
        this.font = font;
        this.resetDimensions();
    }

    /**
     * Set the label of the text.
     * Re-calculates the dimensions of the font after font change.
     * @param {string} label - String of the desired label for the text.
     */
    Text.prototype.setLabel = function(label){
        this.label = label;
        this.resetDimensions();
    }

    /**
     * Equivalent to `setLabel`. Likely created to prevent errors on
     * accidental calls.
     * Re-calculates the dimensions of the font after font change.
     * @param {string} label - String of the desired label for the text.
     */
    Text.prototype.setText = function(label){
        this.label = label;
        this.resetDimensions();
    }

    /**
     * Returns the label of a Text object.
     * @returns {string} String of the Text's current label.
     */
    Text.prototype.getLabel = function(label){
        return this.label;
    }

    /**
     * Equivalent to `getLabel`.  Likely created to prevent errors on accidental
     * calls.
     * Returns the label of a Text object.
     * @returns {string} String of the Text's current label.
     */
    Text.prototype.getText = function(label){
        return this.label;
    }

    /**
     * Returns the width of a Text object.
     * @returns {number} The width of the text.
     */
    Text.prototype.getWidth = function(){
        return this.width;
    }

    /**
     * Returns the height of a Text object.
     * @returns {number} The height of the text.
     */
    Text.prototype.getHeight = function(){
        return this.height;
    }

    /**
     * Checks if the passed point is contained in the text.
     * @param {number} x - The x coordinate of the point being tested.
     * @param {number} y - The y coordinate of the point being tested.
     * @returns {boolean} Whether the passed point is contained in the text.
     */
    Text.prototype.containsPoint = function(x, y){
        return x >= this.x && x <= this.x + this.width &&
               y <= this.y && y >= this.y - this.height;
    }

    module.exports = Text;