text: "use strict";
  
  module.exports = function(Chart) {
  
  	var helpers = Chart.helpers;
  
  	Chart.defaults.global.title = {
  		display: false,
  		position: 'top',
  		fullWidth: true, // marks that this box should take the full width of the canvas (pushing down other boxes)
  
  		fontStyle: 'bold',
  		padding: 10,
  
  		// actual title
  		text: ''
  	};
  
  	var noop = helpers.noop;
  	Chart.Title = Chart.Element.extend({
  
  		initialize: function(config) {
  			helpers.extend(this, config);
  			this.options = helpers.configMerge(Chart.defaults.global.title, config.options);
  
  			// Contains hit boxes for each dataset (in dataset order)
  			this.legendHitBoxes = [];
  		},
  
  		// These methods are ordered by lifecyle. Utilities then follow.
  
  		beforeUpdate: noop,
  		update: function(maxWidth, maxHeight, margins) {
  
  			// Update Lifecycle - Probably don't want to ever extend or overwrite this function ;)
  			this.beforeUpdate();
  
  			// Absorb the master measurements
  			this.maxWidth = maxWidth;
  			this.maxHeight = maxHeight;
  			this.margins = margins;
  
  			// Dimensions
  			this.beforeSetDimensions();
  			this.setDimensions();
  			this.afterSetDimensions();
  			// Labels
  			this.beforeBuildLabels();
  			this.buildLabels();
  			this.afterBuildLabels();
  
  			// Fit
  			this.beforeFit();
  			this.fit();
  			this.afterFit();
  			//
  			this.afterUpdate();
  
  			return this.minSize;
  
  		},
  		afterUpdate: noop,
  
  		//
  
  		beforeSetDimensions: noop,
  		setDimensions: function() {
  			// Set the unconstrained dimension before label rotation
  			if (this.isHorizontal()) {
  				// Reset position before calculating rotation
  				this.width = this.maxWidth;
  				this.left = 0;
  				this.right = this.width;
  			} else {
  				this.height = this.maxHeight;
  
  				// Reset position before calculating rotation
  				this.top = 0;
  				this.bottom = this.height;
  			}
  
  			// Reset padding
  			this.paddingLeft = 0;
  			this.paddingTop = 0;
  			this.paddingRight = 0;
  			this.paddingBottom = 0;
  
  			// Reset minSize
  			this.minSize = {
  				width: 0,
  				height: 0
  			};
  		},
  		afterSetDimensions: noop,
  
  		//
  
  		beforeBuildLabels: noop,
  		buildLabels: noop,
  		afterBuildLabels: noop,
  
  		//
  
  		beforeFit: noop,
  		fit: function() {
  
  			var ctx = this.ctx,
  				valueOrDefault = helpers.getValueOrDefault,
  				opts = this.options,
  				globalDefaults = Chart.defaults.global,
  				display = opts.display,
  				fontSize = valueOrDefault(opts.fontSize, globalDefaults.defaultFontSize),
  				minSize = this.minSize;
  
  			if (this.isHorizontal()) {
  				minSize.width = this.maxWidth; // fill all the width
  				minSize.height = display ? fontSize + (opts.padding * 2) : 0;
  			} else {
  				minSize.width = display ? fontSize + (opts.padding * 2) : 0;
  				minSize.height = this.maxHeight; // fill all the height
  			}
  
  			this.width = minSize.width;
  			this.height = minSize.height;
  
  		},
  		afterFit: noop,
  
  		// Shared Methods
  		isHorizontal: function() {
  			var pos = this.options.position;
  			return pos === "top" || pos === "bottom";
  		},
  
  		// Actualy draw the title block on the canvas
  		draw: function() {
  			var ctx = this.ctx,
  				valueOrDefault = helpers.getValueOrDefault,
  				opts = this.options,
  				globalDefaults = Chart.defaults.global;
  
  			if (opts.display) {
  				var fontSize = valueOrDefault(opts.fontSize, globalDefaults.defaultFontSize),
  					fontStyle = valueOrDefault(opts.fontStyle, globalDefaults.defaultFontStyle),
  					fontFamily = valueOrDefault(opts.fontFamily, globalDefaults.defaultFontFamily),
  					titleFont = helpers.fontString(fontSize, fontStyle, fontFamily),
  					rotation = 0,
  					titleX, 
  					titleY;
  
  				ctx.fillStyle = valueOrDefault(opts.fontColor, globalDefaults.defaultFontColor); // render in correct colour
  				ctx.font = titleFont;
  
  				// Horizontal
  				if (this.isHorizontal()) {
  					titleX = this.left + ((this.right - this.left) / 2); // midpoint of the width
  					titleY = this.top + ((this.bottom - this.top) / 2); // midpoint of the height
  				} else {
  					titleX = opts.position === 'left' ? this.left + (fontSize / 2) : this.right - (fontSize / 2);
  					titleY = this.top + ((this.bottom - this.top) / 2);
  					rotation = Math.PI * (opts.position === 'left' ? -0.5 : 0.5);
  				}
  
  				ctx.save();
  				ctx.translate(titleX, titleY);
  				ctx.rotate(rotation);
  				ctx.textAlign = 'center';
  				ctx.textBaseline = 'middle';
  				ctx.fillText(opts.text, 0, 0);
  				ctx.restore();
  			}
  		}
  	});
  };
  