text: // Copyright (c) 2009 - Quildreen <quildreen@gmail.com>                     
  //                                                                          
  //  Permission is hereby granted, free of charge, to any person              
  //  obtaining a copy of this software and associated documentation files     
  //  (the "Software"), to deal in the Software without restriction,           
  //  including without limitation the rights to use, copy, modify, merge,     
  //  publish, distribute, sublicense, and/or sell copies of the Software,     
  //  and to permit persons to whom the Software is furnished to do so,        
  //  subject to the following conditions:                                     
  //                                                                           
  //  The above copyright notice and this permission notice shall be           
  //  included in all copies or substantial portions of the Software.          
  //                                                                           
  //  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,          
  //  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF       
  //  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND                    
  //  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE   
  //  LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION   
  //  OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION    
  //  WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 
  
  
  /**
   * lily.graphics.font
   *
   * Abstracts font rendering in javascript.
   **/
  lily.defineModule("graphics.font");
  
  /**
   * class lily.graphics.Font
   * 
   * Abstract system-level font rendering.
   **/
  lily.graphics.Font = Class.create(
  {
      /**
       * new lily.graphics.Font(name[, options])
       * - name (String): unique identifier for this font.
       * - options (Object): optional rendering arguments.
       **/
      initialize: function(name)
      {
          var options = Object.extend({
              face: null,
              bold_font: null,
              italic_font: null,
              bold_italic_font: null,
  
              size: 12,
              colour: '#000000',
              letter_spacing: null,
              line_height: 1,
              word_wrap: false,
              text_align: "left",
  
              // wheter we should register this font automatically
              register: true
          }, arguments[1]);
  
          /**
           * lily.graphics.Font#name -> String
           * 
           * The alias of the font for the manager.
           **/
          this.name = name;
  
          /**
           * lily.graphics.Font#font -> String
           * 
           * The font face to use for this font. The format used by this
           * variable (as all face ones) is internal -- it can be a String with
           * the system font name, or an object mapping the characters position
           * in a image.
           **/
          this.font = options.face;
  
          /**
           * lily.graphics.Font#bold_font -> String
           * 
           * The font face to use for this font. The format used by this
           * variable (as all face ones) is internal -- it can be a String with
           * the system font name, or an object mapping the characters position
           * in a image.
           **/
          this.bold_font = options.bold_font;
  
          /**
           * lily.graphics.Font#italic_font -> String
           * 
           * The font face to use for this font. The format used by this
           * variable (as all face ones) is internal -- it can be a String with
           * the system font name, or an object mapping the characters position
           * in a image.
           **/
          this.italic_font = options.italic_font;
  
          /**
           * lily.graphics.Font#bold_italic_font -> String
           * 
           * The font face to use for this font. The format used by this
           * variable (as all face ones) is internal -- it can be a String with
           * the system font name, or an object mapping the characters position
           * in a image.
           **/
          this.bold_italic_font = options.bold_italic_font;
  
          /**
           * lily.graphics.Font#size -> Number
           * 
           * The current (and default) size of this font. This will be used
           * as default option in rendering.
           **/
          this.size = options.size;
          
          /**
           * lily.graphics.Font#letter_spacing -> Number
           * 
           * The amount of spacing to use between letters, in pixels.
           **/
          this.letter_spacing = options.letter_spacing;
  
          /**
           * lily.graphics.Font#line_height -> Number
           * 
           * The size of each line, in percentage.
           **/
          this.line_height = options.line_height;
  
          /**
           * lily.graphics.Font#word_wrap -> Boolean
           * 
           * Whether or not to use word wrapping.
           **/
          this.word_wrap = options.word_wrap;
  
          /**
           * lily.graphics.Font#bold -> Boolean
           * 
           * Whether or not to render the text in bold.
           **/
          this.bold = false;
  
          /**
           * lily.graphics.Font#italic -> Boolean
           * 
           * Whether or not to render the text in italic.
           **/
          this.italic = false;
          
          /**
           * lily.graphics.Font#underline -> Boolean
           * 
           * Whether or not to render the text with an underline.
           **/
          this.underline = false;
          
          /**
           * lily.graphics.Font#overline -> Boolean
           * 
           * Whether or not to render the text with an overline.
           **/
          this.overline = false;
          
          /**
           * lily.graphics.Font#strike -> Boolean
           * 
           * Whether or not to render the text with a strike through.
           **/
          this.strike = false;
  
          /**
           * lily.graphics.Font#colour -> String
           * 
           * The colour in which the text should be rendered, as a CSS
           * colour string.
           **/
          this.colour = options.colour;
  
          /**
           * lily.graphics.Font#text_align -> String
           * 
           * The horizontal alignment of the text.
           **/
          this.text_align = options.text_align;
  
  
          if (options.register) {
              lily.graphics.font.register(this, this.name);
          }
      },
  
      /**
       * lily.graphics.Font#render(text[, surface][, options]) -> lily.graphics.Surface
       * - text (String): the text to render.
       * - surface ([[lily.graphics.Surface]]) - surface to render the text to.
       * - options (Object) - additional rendering options. 
       * 
       * Renders the given text to the given surface. If no surface is provided,
       * one will be created.
       **/
      render: function(text, surface, options)
      {
          /* void */
      }
  });
  
  /*--
   * Manages different kinds of fonts (system and image-based).
   */
  Object.extend(lily.graphics.font, (function() {
      // A dictionary of non-system fonts handled by this object.
      var fonts = {};
  
      /**
       * lily.graphics.font.register(font[, name]) -> undefined
       * - font (Font): font object to register.
       * - name (String): in which name the font should be registered.
       * 
       * Register a new font in the font manager.
       * 
       * If a font name is not given, it'll be extracted from the Font object.
       **/
      function register(font, name)
      {
          name || (name = font.name);
          fonts[name] = font;
      }
  
      /**
       * lily.graphics.font.remove(name) -> undefined
       * - name (String): name of the font to remove.
       * 
       * Removes a previously registered font from the manager. Throws an error
       * if the font is not registered.
       **/
      function remove(name)
      {
          if (fonts[name]) {
              delete fonts[name];
          } else {
              throw new EFontNotRegistered();
          }
      }
  
      /**
       * lily.graphics.font.get(name) -> Font
       * - name (String): name of the font to retrive.
       * 
       * Returns the font registered with the given name.
       **/
      function get(name)
      {
          if (fonts[name]) {
              return fonts[name];
          } else {
              throw new EFontNotRegistered();
          }
      }
  
      /**
       * lily.graphics.font.render(text[, font][, surface][, options]) -> lily.graphics.Surface
       * - text (String): text to render
       * - font (String | Font): font to use as rendering.
       * - surface ([[lily.graphics.Surface]]): surface to render the text to.
       * - options (Object): additional rendering options.
       * 
       * Render the given text with the specified font.
       * 
       * If a font is not given, the function will use the module's
       * default font ([[lily.graphics.font.default_font]]) instead.
       * 
       * If a surface is not given, one'll be created and returned.
       * 
       * The rendering options accepts the same properties you can pass
       * when creating a [[lily.graphics.Font]] object.
       **/
      function render(text, font, surface, options)
      {
          // gets the default font if one wasn't specified
          font || (font = lily.graphics.font.default_font);
          
          if (Object.isString(font)) {
              font = fonts[font];
          }
          if (!font) {
              throw new EFontNotRegistered();
          }
  
          // render the font
          return font.render(text, surface, options);
      }
  
      return {
          /**
           * lily.graphics.font.default_font -> String | Font
           * 
           * The font to use in rendering when one is not provided.
           **/
          default_font: '',
  
          register: register,
          remove: remove,
          get: get,
          render: render
      };
  }()));