﻿/*
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;
}

