﻿/*
Elm.js
Created 1/21/2009 by Dan Roentsch - Ogilvy
*/
function elm()
{  
  //array of made objects
    this.elms = [];
    //incrementing id for each made object
    this.elmId = 0;
}

//the enclosing method
elm.prototype.make = function(element_or_id) {
    var that = this;
    if (that.IsEmpty(element_or_id)) { return this; }
    var l = element_or_id;
    var ll = null;
    if (typeof (l) == "string") {
        ll = document.getElementById(l);
        if (ll === null) { return this; }
    }
    else {
        ll = l;
    }

    var theValue = null;
    var theValues = [];
    var isHidden = null;
    var regex = null;
    ll.isValid = true;
    ll.remove = function() {
        if (that.IsEmpty(this.parentNode)) { return this; }
        this.parentNode.removeChild(this);
    }
    ;
    ll.test = function(is_required) {
        var value = this.getValue();
        //the default is required
        is_required = (that.IsEmpty(is_required) || is_required === true);

        if (is_required === true) {
            if (that.IsEmpty(value) || value == "" || value == "NULL" || value === false) return false;
        }
        else {
            if (that.IsEmpty(value) || value == "" || value == "NULL" || value === false) return true;
        }

        if (!that.IsEmpty(regex)) {
            return regex.test(value)
        }
        return true;
    }
    ;
    ll.setRegex = function(regular_expression) {
        if (that.IsEmpty(regular_expression)) {
            regular_expression = null;
        }
        regex = regular_expression;
    }
    ;
    ll.getValue = function() {
        switch (this.tagName.toUpperCase()) {
            case "INPUT":
                if (this.getAttribute("type").toUpperCase() == "TEXT") return this.value;
                if (this.getAttribute("type").toUpperCase() == "RADIO") return this.checked;
                if (this.getAttribute("type").toUpperCase() == "CHECKBOX") return this.checked;
                break;
            case "SELECT":
                if (typeof (this.options) !== undefined && this.options !== null && this.selectedIndex !== null) {
                    return this.options[this.selectedIndex].value;
                }
                break;
            case "BUTTON":
                if (typeof (this.textContent) !== undefined && this.textContent !== null) return this.textContent;
                if (typeof (this.innerText) !== undefined && this.innerText !== null) return this.innerText;
                break;
            default:
                if (typeof (this.innerHTML) !== undefined && this.innerHTML !== null) return this.innerHTML;
        }
        return null;
    }
    ;
    ll.hasField = function(data_field) {
        if (that.IsEmpty(data_field)) { return false; }
        if (that.IsEmpty(this.DataFields.length) || this.DataFields.length == 0) { return false; }
        var casedDF = data_field.toUpperCase();
        for (var i = 0; i < this.DataFields.length; i++) {
            if (this.DataFields[i].toUpperCase() == casedDF) { return true; }
        }
        return false;
    }
    ;
    ll.getPredicate = function() {
        //prefix is expected to be "pred:"
        for (var i = 0; i < this.DataFields.length; i++) {
            var field = this.DataFields[i];
            if (field.toUpperCase().indexOf("PRED:") != -1) {
                var s = field.split(":");
                if (that.IsEmpty(s.length)) return null;
                return s[1];
            }
        }
    }
    ;
    ll.setStyle = function(attrib_value) {
        if (that.IsEmpty(attrib_value)) return null;

        var styleString = null;
        var styleName = null;
        var styleValue = null;
        var camelize = function(a) {
            a = a.toLowerCase();
            var dash = a.indexOf("-");
            var camel = a;
            var humper = null;
            if (dash != -1) {
                humper = a.split("-");
                var hump = humper[1].toUpperCase().charAt(0);
                var rest = humper[1].substring(1);
                camel = humper[0] + hump + rest;
            }
            return camel;
        }
        //if it's a string
        if (typeof (attrib_value) == "string") {
            //if it's multiple styles
            var splitPos = attrib_value.indexOf(";");
            if (splitPos != -1 && splitPos < attrib_value.length + 1) {
                attrib_value = attrib_value.split(";");
            }
            else {
                //if it's one style.
                styleString = attrib_value.replace(";", "");
                styleName = camelize(styleString.split(":")[0]);

                styleValue = styleString.split(":")[1];
                this.style[styleName] = styleValue;
                return this;
            }
        }

        //if it's an array
        if (typeof (attrib_value) == "object") {
            for (var i = 0; i < attrib_value.length; i++) {
                styleString = attrib_value[i].replace(";", "");
                styleName = camelize(styleString.split(":")[0]);
                styleValue = styleString.split(":")[1];
                this.style[styleName] = styleValue;
            }
            return this;
        }
    }
    ;
    ll.setValue = function(attrib_name, attrib_value) {
        if (attrib_name.toUpperCase() == "STYLE") {
            this.setStyle(attrib_value);
            return this;
        }

        if (that.IsEmpty(attrib_value)) {
            this.setViewValue(attrib_name);
            return this;
        }

        var attr = document.createAttribute(attrib_name);
        attr.nodeValue = attrib_value;

        try {
            this.setAttributeNode(attr);
        }
        catch (err) {
            ;
        }
        return this;
    }
    ;
    ll.setViewValue = function(in_value) {
        switch (this.tagName.toUpperCase()) {
            case "INPUT":
                if (this.getAttribute("type").toUpperCase() == "TEXT") this.value = in_value;
                if (this.getAttribute("type").toUpperCase() == "RADIO") this.checked = in_value;
                if (this.getAttribute("type").toUpperCase() == "CHECKBOX") this.checked = in_value;
                break;
            case "SELECT":
                this.options[this.selectedIndex].value = in_value;
                break;
            case "BUTTON":
                if (typeof (this.textContent) !== undefined && this.textContent !== null) this.textContent = in_value;
                if (typeof (this.innerText) !== undefined && this.innerText !== null) this.innerText = in_value;
                break;
            default:
                if (typeof (this.innerHTML) !== undefined && this.innerHTML !== null) this.innerHTML = in_value;
        }
        return this;
    }
    ;
    ll.setClass = function(attrib_value) {
        if (that.IsEmpty(attrib_value)) return null;
        if (this.usesClass(attrib_value)) return;
        this.setValue("class", this.theValues.join(" ") + attrib_value);
    }
    ;
    ll.pushStyle = function(property_name, property_value) {
        if (that.IsEmpty(property_name)) { return; }
        if (that.IsEmpty(property_value)) { return; }
        var trim = /^\s+|\s+$/g;

        var pn = property_name.replace(trim, "");

        var pv = typeof (property_value) == "string" ? property_value.replace(trim, "") : property_value;

        this.setStyle(pn + ":" + pv);
    }
    ;
    //pushStyles pushes an array of style objects
    //each style object must consist of a name property and a value property
    ll.pushStyles = function(style_array) {
        if (that.IsEmpty(style_array)) return;
        if (typeof (style_array) != "object") return;
        for (var i = 0; i < style_array.length; i++) {
            if (!that.IsEmpty(style_array[i].name) && !that.IsEmpty(style_array[i].value)) {
                this.pushStyle(style_array[i].name, style_array[i].value);
            }
        }
    }
    ;
    // pushValue()
    ll.hide = function() {
        //this.pushStyle("display","none");
        this.pushStyle("visibility", "hidden");
        isHidden = true;
        return;
    }
    ;
    // hide()
    ll.show = function() {
        //this.pushStyle("display","none");
        this.pushStyle("visibility", "visible");
        isHidden = false;
        return;
    }
    ;
    // show()
    ll.showHide = function() {
        if (isHidden) this.show();
        else this.hide();
        return;
    }
    ;
    //addText.  Add text to a given element, append that element to this element.
    //style = optional style to add
    //returnHTML = true if you want the HTML added to the innerHTML rather than created
    //              as a text node
    ll.addText = function(text_to_add, element_type, style, returnHTML) {

        if (that.IsEmpty(text_to_add)) return;
        var HasElementType = !(that.IsEmpty(element_type));
        var HasStyle = !(that.IsEmpty(style));
        var IsStyleArray = (HasStyle && typeof (style) == "object");
        //explicit and implicit HTML detected
        if (that.IsEmpty(returnHTML)) {
            if ((text_to_add.indexOf("<") == -1 || text_to_add.indexOf(">") == -1)) {
                returnHTML = false;
            }
            else {
                returnHTML = true;
            }
        }
        var tn = document.createTextNode(text_to_add);
        var theNode = tn;
        if (HasElementType) {
            var et = document.createElement(element_type);
            et.appendChild(tn);
            theNode = et;
        }
        if (!returnHTML) {
            this.appendChild(theNode);
        }
        var a_node = that.make(theNode);
        if (IsStyleArray) {
            for (var i = 0; i < style.length; i++) {
                a_node.pushStyle(style[i].name, style[i].value);
            }
        }
        else {
            if (HasStyle) {
                a_node.setStyle(style);
            }
        }
        if (!returnHTML) return a_node;
        this.innerHTML += a_node.innerHTML;
    }
    ;
    ll.addElement = function(element_type, style) {
        if (that.IsEmpty(element_type)) return;
        var HasStyle = !(that.IsEmpty(style));
        var IsStyleArray = (HasStyle && typeof (style) == "object");
        var theNode = document.createElement(element_type);
        this.appendChild(theNode);
        var a_node = that.make(theNode);
        if (IsStyleArray) {
            for (var i = 0; i < style.length; i++) {
                a_node.pushStyle(style[i].name, style[i].value);
            }
        }
        else {
            if (HasStyle) {
                a_node.setStyle(style);
            }
        }
        return a_node;
    }
    ;
    ll.moveTo = function(x_pos, y_pos) {
        this.positioning(x_pos, y_pos, "absolute");
        return;
    }
    ;
    ll.offsetTo = function(x_pos, y_pos) {
        this.positioning(x_pos, y_pos, "relative");
        return;
    }
    ;
    ll.positioning = function(x_pos, y_pos, position_type) {
        if (that.IsEmpty(x_pos) || that.IsEmpty(y_pos) || that.IsEmpty(position_type)) return;
        var x = x_pos;
        var y = y_pos;

        this.pushStyle("position", position_type);
        this.pushStyle("top", y + "px");
        this.pushStyle("left", x + "px");

        return;
    }
	;
    ll.addSelectors = function() {
        //associate any number of strings with the variable.
        if (arguments.length > 1) {
            if (that.IsEmpty(this.DataFields)) this.DataFields = [];
            var ary = Array.prototype.slice.call(arguments);
            for (var i = 0; i < ary.length; i++) {
                this.DataFields.push(ary[i]);
            }
        }
    }
	;
    ll.elmId = this.elmId;
    ll.DataFields = [];
    // build the userid array
    if (arguments.length > 1) {
        var ary = Array.prototype.slice.call(arguments);
        ll.DataFields = ary.slice(1);
    }
    this.elmId++;
    this.elms.push(ll);

    return ll;
}

// end make()
elm.prototype.showHideAll = function()
{
    for (i=0;i<this.elms.length;i++)
    {
        this.elms[i].showHide();
    }
}
elm.prototype.select = function(data_field)
{
    if (this.IsEmpty(data_field)) return this.wrapArray(this.elms);

    var return_array = [];
    for (i=0;i<this.elms.length;i++)
    {
        if (typeof(this.elms[i].DataFields) !== "undefined") var df = this.elms[i].DataFields;
        if (df != null)
        {
            for (var j = 0; j < df.length; j++)
            {
                if (df[j] == data_field) return_array.push(this.elms[i]);
            }
        }
    }

    if (return_array.length==1)
    {
        return return_array[0];
    }
    return this.wrapArray(return_array);
}    
elm.prototype.selectClass = function(class_name)
{
    if (this.IsEmpty(class_name)) return this.wrapArray(this.elms);
    var return_array = [];
    for (i=0;i<this.elms.length;i++)
    {
        if (this.elms[i].usesClass(class_name)) return_array.push(this.elms[i]);
    }
    return this.wrapArray(return_array);
}
elm.prototype.selectById = function(field)
{
    if (this.IsEmpty(field)) return null;
    if (this.IsEmpty(this.elms) || this.elms.length == 0) return null; 

    var return_array = [];
    for (i=0;i<this.elms.length;i++)
    {
        if (this.elms[i].id.toUpperCase == field.toUpperCase()) return this.elms[i];
    }
    return null;
}    
elm.prototype.wrapArray = function(raw_array)
{
    var that = this;
    if (typeof(raw_array) != "object")
    {
        return null;
    }
    var r = raw_array;
    r.test = function(is_required, regular_expression)
    {
        if (that.IsEmpty(regular_expression))
        {
            regular_expression = null;
        }
        if (that.IsEmpty(is_required))
        {
            is_required = true;
        }
        for (i=0;i<this.length;i++)
        {
            this[i].test(is_required, regular_expression);
        }
    }
    ;
    r.select = function(data_field)
    {
        if (that.IsEmpty(data_field)) return that.wrapArray(this);

        var return_array = [];
        for (i=0;i<this.length;i++)
        {
            if (typeof(this[i].DataFields) !== "undefined") var df = this[i].DataFields;
            if (df != null)
            {
                for (var j = 0; j < df.length; j++)
                {
                    if (df[j] == data_field) return_array.push(this[i]);
                }
            }
        }
        if (return_array.length==1)
        {
            return return_array[0];
        }
        return that.wrapArray(return_array);
    }
    ;
    r.setValue = function(attrib_name, attrib_value)
    {
        if (that.IsEmpty(attrib_name)) return this;
        if (that.IsEmpty(attrib_value))
        {
            for (i=0;i<this.length;i++)
            {
                this[i].setValue(attrib_name);
            }
        }
        else
        {
            for (i=0;i<this.length;i++)
            {
                this[i].setValue(attrib_name, attrib_value);
            }
        }
        return this;
    }
    ;
    //THE LINE
    //toggle display all elements in the array
    r.showHide = function()
    {            
        for (i=0;i<this.length;i++)
        {
            this[i].showHide();
        }
    }
    ;
    r.show = function()
    {            
        for (i=0;i<this.length;i++)
        {
            this[i].show();
        }
    }
    ;
    r.hide = function()
    {            
        for (i=0;i<this.length;i++)
        {
            this[i].hide();
        }
    }
    ;
    //set a style on all elements in the array
    r.setStyle = function(attrib_value)
    {
        if (that.IsEmpty(attrib_value)) return;
        for (i=0;i<this.length;i++)
        {
            this[i].setStyle(attrib_value);
        }            
    }
    ;
    //get the first element of an array
    r.first = function()
    {
        if (that.IsEmpty(this[0])) return null;
        return this[0];
    }
    ;
    //get the first element of an array
    r.pushStyle = function(property_name, property_value)
    {
        if (that.IsEmpty(property_name) || that.IsEmpty(property_value)) return null;
        for (i=0;i<this.length;i++)
        {
            this[i].pushStyle(property_name, property_value);
        }            
    }
    ;
    r.moveTo = function(x_pos,y_pos)
    {
        if (that.IsEmpty(x_pos) || that.IsEmpty(y_pos)) return null;
        for (i=0;i<this.length;i++)
        {
			this[i].moveTo(x_pos, y_pos);			
        }            
		return;
    }
    ;
    r.offsetTo = function(x_pos,y_pos)
    {
        if (that.IsEmpty(x_pos) || that.IsEmpty(y_pos)) return null;
        for (i=0;i<this.length;i++)
        {
			this[i].offsetTo(x_pos, y_pos);			
        }            
		return;
    }
    ;
    r.IsWrapped = true;
    return r;
}
elm.prototype.IsEmpty = function(test_var)
{
    if (typeof(test_var) === "undefined") return true;
    if (test_var === null) return true;
    if (test_var == "null") return true;
    return false;
}
elm.prototype.addText = function(text_to_add, element_type, style)
{
    if (this.IsEmpty(text_to_add)) return;
    var HasElementType = !(this.IsEmpty(element_type));
    var HasStyle = !(this.IsEmpty(style));
    var IsStyleArray = (HasStyle && typeof(style) == "object");
    var tn = document.createTextNode(text_to_add);
    var theNode = tn;
    if (HasElementType)
    {
        var et = document.createElement(element_type);
        et.appendChild(tn);
        theNode = et;
    }
    var a_node = this.make(theNode);
    if (IsStyleArray)
    {
		for (var i = 0; i < style.length; i++)
		{
			a_node.pushStyle(style[i].name,style[i].value);
		}
    }
    else
    {
		if (HasStyle)
		{
			a_node.setStyle(style);                
		}
    }
    return a_node;
}

