jQuery.beautyOfCode = {
  initialized: false,

  settings: {

    // hide line numbers?
    noGutter: false,

    // show copy, plain, ... links
    addControls: true,

    // collapse to control bar. cant be used
    // with addControls set to false
    collapse: false,

    // show column numbers
    showColumns: false,

    // start with another line number?
    firstLine: 1
  },

  brushByAlias: {},

  init: function (clipboardSwf, settings) {
    dp.SyntaxHighlighter.ClipboardSwf = clipboardSwf;

    if (settings)
      jQuery.extend(jQuery.beautyOfCode.settings, settings);

    if (jQuery.beautyOfCode.isInitialized)
      return;

    // creates a map of each registered brush by alias
    jQuery.each(dp.sh.Brushes, function (i, brush) {
      var aliases = brush.Aliases;

      if(aliases == null)
       return;

      jQuery.each(aliases, function (ii, alias) {
        jQuery.beautyOfCode.brushByAlias[alias] = brush;
      });
    });

    jQuery.beautyOfCode.isInitialized = true;
  },

  addCssForBrush: function (brush, highlighter) {
    if (brush.isCssInitialized)
      return;

    var headNode = $("head")[0];
    if(highlighter.Style && headNode)
    {
      var styleNode = document.createElement('style');
      styleNode.setAttribute('type', 'text/css');

      if(styleNode.styleSheet) // for IE
        styleNode.styleSheet.cssText = highlighter.Style;
      else // for everyone else
        $(styleNode).text(highlighter.Style);

      headNode.appendChild(styleNode);
    }

    brush.isCssInitialized = true;
  },

  beautifyAll: function() {
    jQuery("pre.code:has(code[class])").each(function (i, item) {

      function getOptionValue(name, list)
      {
        var regex = new RegExp('^' + name + '\\[(\\w+)\\]$', 'gi');
        var matches = null;

        for(var i = 0; i < list.length; i++)
         if((matches = regex.exec(list[i])) != null)
          return matches[1];

        return null;
      }

      var $item = jQuery(item);
      var $code = $item.children("code");
      var code = $code[0];

      var options = code.className.split(" ");
      var language = options[0];

      var settings = {};

      if ($code.hasClass("boc-nogutter"))
        settings.noGutter = true;

      if ($code.hasClass("boc-nocontrols"))
        settings.addControls = false;

      if ($code.hasClass("boc-showcolumns"))
        settings.showColumns = true;

      if ($code.hasClass("boc-collapse"))
        settings.collapse = true;        

      var firstLine = getOptionValue("boc-firstline", options, 1);
      if (firstLine)
        settings.firstLine = firstLine;

      $item.beautifyCode(language, settings);
    });
  }
};

jQuery.fn.beautifyCode = function (language, settings) {

  var saveLanguage = language;
  var saveSettings = settings;

  // iterate all elements
  this.each( function (i, item) {
    var $item = jQuery(item);

    var settings = jQuery.extend({}, jQuery.beautyOfCode.settings, saveSettings);

    var brush = jQuery.beautyOfCode.brushByAlias[saveLanguage];

    if (!brush)
      return;

    // instantiate brush
    highlighter = new brush();

    // set brush options
    jQuery.extend(highlighter, settings);

    jQuery.beautyOfCode.addCssForBrush(brush, highlighter);

    // IE Bug?: code in pre has to be skipped
    // in order to preserver line breaks.
    if ($item.is("pre") && ($code = $item.children("code")))
      $item.text($code.text());

    highlighter.Highlight($item.html());
    highlighter.source = item;

    $item.replaceWith(highlighter.div);
  });
}

