  theme_objects = [];

  theme_objects[0] = {
    "bg_c" : "rgb(39,39,39)",
    "bg_lh_c" : "rgb(60,60,60)",
    "sb_c" : "rgb(0,0,0)",
    "sb_t_c" : "rgb(160, 160, 160)",
    "c_c" : "rgb(255,255,255)",
    "pln_c" : "rgb(255, 236, 203)",
    "str_c" : "rgb(255,119,255)",
    "kwd_c" : "rgb(54,191,255)",
    "com_c" : "rgb(91,222,7)",
    "typ_c" : "rgb(61,168,237)",
    "lit_c" : "rgb(61,168,0)",
    "pun_c" : "rgb(255,236,203)",
    "tag_c" : "rgb(54,191,255)",
    "atn_c" : "rgb(255,255,0)",
    "atv_c" : "rgb(0,255,255)",
    "dec_c" : "rgb(61,168,237)",
    "font_size" : 16,
    "font" : "16px monospace"
  };

function ConstructorizerReadOnly(pre_object,element,editor){
  prettyPrint();
  this.canvas = element;
  this.context = this.canvas.getContext("2d");
  this.element = element;  
  this.editor = editor;
  this.pre_object = pre_object;
  this.theme_object = theme_objects[0];

  this.addExtraHeight = function(added_height){
    this.extra_height += added_height;
  }

  this.plainContent = function(){
    var plain_content = "";
    this.pre_object.children().each(function(){
      plain_content+=$(this).html();
    });
    plain_content = this.cleanHTMLSpecialChars(plain_content);
    return plain_content;
  }

  this.cleanHTMLSpecialChars = function (dirty_string){
    dirty_string = dirty_string.replace(/&lt;/g , "<");
    dirty_string = dirty_string.replace(/&gt;/g , ">");
    dirty_string = dirty_string.replace(/&nbsp;/g , " ");
    dirty_string = dirty_string.replace(/<br>/g , "\n");
    return dirty_string;
  }

  this.setDefaults = function(){
    this.canvas.width = this.editor.width();
    this.canvas.height = this.editor.height();
    this.width = this.canvas.width;
    this.height = this.canvas.height;
    this.background_color = this.theme_object["bg_c"];
    this.line_highlighter_color = this.theme_object["bg_lh_c"];
    this.font_size = this.theme_object["font_size"];
    this.context.font = this.theme_object["font"];
    this.sidebar_color = this.theme_object["sb_c"];
    this.sidebar_text_color = this.theme_object["sb_t_c"];
    this.sidebar_width = this.context.measureText(this.getNumLines()+' ').width;
    this.text_indent = this.sidebar_width+5;
    this.top_spacing = 5;
    this.cursor_color = this.theme_object["c_c"];
    this.cursor_position = 14;
    this.cursor_blink_count = 0;
    this.context.textBaseline = "top";
    this.shift_down = false;
    this.has_focus = false;
  }
		
  this.setBackgroundColor = function(color){
    this.background_color = color;
  }

  this.resetValues = function(){
    this.canvas.width = this.editor.width();
    this.canvas.height = this.editor.height();
    this.width = this.canvas.width;
    this.height = this.canvas.height;
    this.context.font = this.theme_object["font"];
    this.context.textBaseline = "top";
    this.sidebar_width = this.context.measureText(this.getNumLines()+' ').width;
    this.text_indent = this.sidebar_width+5;
  }
		
  this.getNumLines = function(){
    return this.plainContent().split("\n").length;
  }
		
  this.getHeightPerLine = function(){
    return this.font_size+2;
  }
		
  this.getLengthOfLongestLine = function(){
    var lines = this.plainContent().split("\n");
    var largest = 0;
    for(var i=0;i<lines.length;i++){
      var line_length = this.context.measureText(lines[i]).width+this.text_indent;
      if( line_length > largest){
        largest=line_length;
      }
    }
    return largest;
  }

  this.getLineNumber = function(){
    var textLeft = this.plainContent().substring(0,this.cursor_position);
    var lineNumber = textLeft.split("\n").length-1;
    return lineNumber;
  }
		
  this.setDefaults();		
		
  this.drawSpanText = function(span_object,prev_text,i){
    if(span_object.attr('class')=="str"){this.context.fillStyle=this.theme_object["str_c"];}
    else if(span_object.attr('class')=="kwd"){this.context.fillStyle=this.theme_object["kwd_c"];}
    else if(span_object.attr('class')=="com"){this.context.fillStyle=this.theme_object["com_c"];}
    else if(span_object.attr('class')=="typ"){this.context.fillStyle=this.theme_object["typ_c"];}
    else if(span_object.attr('class')=="lit"){this.context.fillStyle=this.theme_object["lit_c"];}
    else if(span_object.attr('class')=="pln"){this.context.fillStyle=this.theme_object["pln_c"];}
    else if(span_object.attr('class')=="pun"){this.context.fillStyle=this.theme_object["pun_c"];}
    else if(span_object.attr('class')=="tag"){this.context.fillStyle=this.theme_object["tag_c"];}
    else if(span_object.attr('class')=="atn"){this.context.fillStyle=this.theme_object["atn_c"];}
    else if(span_object.attr('class')=="atv"){this.context.fillStyle=this.theme_object["atv_c"];}
    else if(span_object.attr('class')=="dec"){this.context.fillStyle=this.theme_object["dec_c"];}
    else{this.context.fillStyle=this.theme_object["pln_c"];}
    this.context.fillText(span_object.text(), this.text_indent+this.context.measureText(prev_text).width, this.top_spacing+this.getHeightPerLine()*i);
    return span_object.text();
  }

  this.drawLineText = function(lineText,i,max,last_span){
    if(i!=0){
      lineText = last_span+lineText;
    }
    if(i!=max-1){
      last_span = lineText.substr(lineText.lastIndexOf("<"),lineText.lastIndexOf(">")-lineText.lastIndexOf("<")+1);
    }
    lineText = lineText+last_span;
    lineText = '<pre>'+lineText+'</pre>';
    var $lineText_object = $(lineText);
    var prev_text = "";
    var this_object = this;
    $lineText_object.filter('pre').children().each(function(){
      prev_text+=this_object.drawSpanText($(this),prev_text,i);
    });
  
    if(i!=max-1){
      return last_span;
    }
    else{
      return "";
    }
  }
		
  this.draw = function(){
    //Reset Values in case user changed window size
    this.resetValues();
    //Draw Background
    this.context.fillStyle = this.background_color;
    this.context.fillRect(0, 0, this.width, this.height);
    //Draw Line Highligher
    if(this.has_focus){
      this.context.fillStyle = this.line_highlighter_color
      this.context.fillRect(this.sidebar_width,this.getLineNumber()*this.getHeightPerLine()+this.top_spacing,this.width-this.sidebar_width,this.getHeightPerLine());		  
    }
    //Draw Text
    var contentSplitted = this.pre_object.html().split("<br>");
    var last_span = "";
    for(var i=0;i<contentSplitted.length;i++){
      last_span = this.drawLineText(contentSplitted[i],i,contentSplitted.length,last_span);
    }
    //Draw Sidebar
    this.context.fillStyle = this.sidebar_color;
    this.context.fillRect(0, 0, this.sidebar_width, this.height);
    this.context.fillStyle = this.sidebar_text_color;
    for(var j=0;j<this.plainContent().split("\n").length;j++){
      this.context.fillText(j+1, 3, this.top_spacing+this.getHeightPerLine()*j);
    }          
    //If Text Is Too Short set min height else fit height
    if( (this.top_spacing + this.getNumLines()*this.getHeightPerLine()) < 20){
      this.editor.height(20);
    }
    else{
      this.editor.height(this.top_spacing + this.getNumLines()*this.getHeightPerLine());
    }
    if(this.editor.width()<1000){
      this.editor.width(1000);
    }
    else if(this.getLengthOfLongestLine() <980){
      this.editor.width(1000);
    }
    else{
      //this.editor.width( this.getLengthOfLongestLine()+20 );
    }
    //Draw Cursor
    if(this.cursor_blink_count<6 && this.has_focus){
      this.context.fillStyle = this.cursor_color;
      var textLeft = this.plainContent().substring(0,this.cursor_position);
      var lineNumber = textLeft.split("\n").length-1;
      var lineTextLeft = textLeft.split("\n")[lineNumber];
      var cursorOffsetX = this.context.measureText(lineTextLeft).width;
      this.context.fillRect(cursorOffsetX+this.text_indent,this.top_spacing+lineNumber*this.getHeightPerLine(),1,this.font_size);
    }
    if(this.cursor_blink_count>12){
      this.cursor_blink_count=0;
    }
    this.cursor_blink_count++;
  }

  this.getLineText = function(lineNumber){
    return this.plainContent().split("\n")[lineNumber];
  }

  this.draw();
  this.resetValues();
  this.draw();
}

