var ElementMaxHeight = function() {

  this.initialize.apply(this, arguments);

}



/**

 * ElementMaxHeight constructor

 * @param string cssQuery

 * @param ...

 * 

 * cssQuery format is '[tag](#|.)(selectorName)[:parent]' where:

 *   [] - optional, () - required

 *   tag - (X)HTML tag name

 *   #|. - id or class separator

 *   selectorName - id or class name

 *   :parent - refers to element's parent node

 * Example:

 *   ElementMaxHeight('.maxheight', 'br.vspacer:parent');

 *   // expands all elements with class 'maxheight'

 *   // and all blocks containing <br class="vspacer" />

 */

ElementMaxHeight.prototype = {

  initialize: function() {

    var __args = arguments;

    var __object = this;

    var __run = this.run;

    if (window.addEventListener) {

      window.addEventListener('load', function() {return __run.apply(__object, __args)}, false);

    } else if (window.attachEvent) {

      window.attachEvent('onload', function() {return __run.apply(__object, __args)});

    }

  },



  run: function() {

    this.elements = this.findElements(arguments);

    this.textElement = document.createElement('span');

    this.textElement.appendChild(document.createTextNode('A'));

    this.textElement.style.display = 'block';

    this.textElement.style.position = 'absolute';

    this.textElement.style.fontSize = '1em';

    this.textElement.style.top = '-1000px';

    this.textElement.style.left = '-1000px';

    document.body.appendChild(this.textElement);

    this.textElementHeight = this.textElement.offsetHeight;

    var __object = this;

    var __checkFontSize = this.checkFontSize;

    this.checkFontSizeInterval = window.setInterval(function() {return __checkFontSize.apply(__object)}, 500);



    this.expand();



    // Refresh elements height onResize event

    var __expand = this.expand;

    if (window.addEventListener) {

      window.addEventListener('resize', function(event) {return __expand.apply(__object, [( event || window.event)])}, false);

    } else if (window.attachEvent) {

      window.attachEvent('onresize', function(event) {return __expand.apply(__object, [( event || window.event)])});

    }

  },

  

  findElements: function(cssQuery) {

    var elements = [], items = [], item;

    for (var i = 0; i < cssQuery.length; i++) {

      // Explode cssQuery: ["tagName", "# | .", "Id | className", ":", "parent"]

      var q = cssQuery[i].replace(/\.|\:|#]/gi, ',$&,').split(',');

      if (q[1] == '#') { // find by Id

        if (q[4] && q[4] == 'parent') {

          item = document.getElementById(q[2]).parentNode;

        } else {

          item = document.getElementById(q[2]);

        }



        if (q[0].length == 0 || q[0] == '*' || (q[0].length > 0 && q[0].toLowerCase() == item.tagName.toLowerCase())) {

          elements.push(item);

        }

      } else if (q[1] == '.') { // find by className

      

          items = document.getElementsByClassName(q[2]);

       

        for (var j = 0; j < items.length; j++) {            

          if (q[0].length == 0 || q[0] == '*' || (q[0].length > 0 && q[0].toLowerCase() == items[j].tagName.toLowerCase())) {

            elements.push((q[4] && q[4] == 'parent') ? items[j].parentNode : items[j]);

          }

        }

      }

    }



    return elements;

  },



  expand: function() {

    this.reset();

    for (var i = 0; i < this.elements.length; i++) {

      var col = getBoxLayout(this.elements[i]);

      this.elements[i].style.height = (

        getBoxLayout(this.elements[i].parentNode).height

        - (col.marginTop + col.marginBottom

           + col.borderTop + col.borderBottom

           + col.paddingTop + col.paddingBottom)) + 'px';

  	}

  },



  reset: function() {

    for (var i = 0; i < this.elements.length; i++) {    

      this.elements[i].style.height = 'auto';

    }

  },



  checkFontSize: function() {

  	var height = this.textElement.offsetHeight;

  	if(this.textElementHeight != height) {

  		this.textElementHeight = height;

  		this.expand();

  	}

  }

}



document.getElementsByClassName = function(className, parentElement) {

  if (!!document.evaluate) {

    var results = [];

    var query = document.evaluate(

        ".//*[contains(concat(' ', @class, ' '), ' " + className + " ')]",

        parentElement || document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);

    for (var i = 0, length = query.snapshotLength; i < length; i++) {

      results.push(query.snapshotItem(i));

    }

    return results;

  } else {

    var children = (parentElement || document.body).getElementsByTagName('*');

    var elements = [], child;

    for (var i = 0, length = children.length; i < length; i++) {

      child = children[i];

      if (child.className.length != 0 &&

          (child.className == className ||

           child.className.match(new RegExp("(^|\\s)" + className + "(\\s|$)")))) {

        elements.push(child);

      }

    }

    return elements;

  }

}



function getStyle(element, style) {

   if (window.getComputedStyle) {

    return window.getComputedStyle(element, null)[style];

  } else if (element.currentStyle) {

    return element.currentStyle[style];

  }

}



function getBoxLayout(element) {

    var styleNames = {

      'marginTop': 'marginTop', 'marginRight': 'marginRight',

      'marginLeft': 'marginLeft', 'marginBottom': 'marginBottom',

      'borderTopWidth': 'borderTop', 'borderRightWidth': 'borderRight',

      'borderLeftWidth': 'borderLeft', 'borderBottomWidth': 'borderBottom',

      'paddingTop': 'paddingTop', 'paddingRight': 'paddingRight',

      'paddingLeft': 'paddingLeft', 'paddingBottom': 'paddingBottom'

    };



    var box = {}, value = 0;

    for (var styleName in styleNames) {

      value = getStyle(element, styleName);

      box[styleNames[styleName]] = isNaN(parseInt(value)) ? 0 : parseInt(value);

    }

    box.width = element.offsetWidth - (box.paddingLeft + box.paddingRight + box.borderLeft + box.borderRight);

    box.height = element.offsetHeight - (box.paddingTop + box.paddingBottom + box.borderTop + box.borderBottom);

    return box;

};



// Create new ElementMaxHeight instance

new ElementMaxHeight(

	'.column_center',

	'.indent_center',

	'.side_bar',

	'.inside',

	'.equal'

);



