function instanceOf(object, constructorFunction) {
  while (object != null) {
    if (object == constructorFunction.prototype)
     {return true}
     object = object.__proto__;
  }
  return false;
};

function arrayContains( arrayToVerify, arrayValue ) {
    var state = false;
    if( arrayToVerify != null && arrayToVerify.length > 0 ) {
        for( var i=0; i < arrayToVerify.length && state == false ; i++ ) {
            state = arrayToVerify[ i ] == arrayValue;
        }
    }
    return state;
};

function mergeArrays( baseArray1, baseArray2 ) {
    var mergedArray = addAllToArray( new Array(0), baseArray1 );
    mergedArray = addAllToArray( mergedArray, baseArray2 );
    return mergedArray;
};

function addAllToArray( baseArray, arrayToAdd ) {

    if( baseArray == null ) {
        baseArray = new Array(0);
    }
    if( arrayToAdd != null && arrayToAdd.length > 0 ) {
        for( var i=0; i < arrayToAdd.length; i++ ) {
            baseArray.push( arrayToAdd[i] );
        }
    }

    return baseArray;
};

function getNodesWithNameAndAttributeValue( baseNode, nodeName, attributeName, attributeValue ) {
    var nodes = new Array(0);

    if( nodeName != null && nodeName.length > 0 && baseNode != null ) {
        var nodesWithMatchingName = baseNode.getElementsByTagName( nodeName );

        if( nodesWithMatchingName != null && nodesWithMatchingName.length > 0 ) {
            if( attributeName != null && attributeName.length > 0 ) {

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

                    var nextNode = nodesWithMatchingName.item( i );

                    var attributeToVerify = getAttributeNode( nextNode, attributeName );

                    if( attributeValue != null && attributeValue.length > 0 ) {
                        if( attributeToVerify != null && attributeToVerify.value == attributeValue ) {
                            nodes.push( nextNode );
                        }
                    } else {
                        nodes.push( nextNode );
                    }

                }
            }
        }
    }

    return nodes;
};

function getAttributeNode( baseNode, attributeName ) {
    var attrNode = null;

    if( baseNode != null && attributeName != null && attributeName.length > 0 ) {
        attrNode = baseNode.attributes.getNamedItem( attributeName );
        if( attrNode == null ) {
            attrNode = baseNode.getAttributeNode( attributeName );
        }
    }

    return attrNode;
};

function setAttributeValueForNode( baseNode, attributeName, attributeValue ) {
    if( baseNode != null && attributeName != null && attributeName.length > 0 ) {

        if( attributeName == "class" ) {
            // IE fix (damn thing)
            baseNode.className = attributeValue;
        } else {
            var attrNode = getAttributeNode( baseNode, attributeName );
            if( attrNode != null ) {
                attrNode.value = attributeValue;

            } else {
                baseNode.setAttribute( attributeName, attributeValue );
            }

            if( getAttributeNodeValue( baseNode, attributeName ) != attributeValue ) {
                //todo: implement fallback                
            }
        }

    }
};

function removeAttributeFromNode( baseNode, attributeName ) {
    if( baseNode != null && attributeName != null && attributeName.length > 0 ) {
        if( attributeName == "class" ) {
            //alert( "IE!!" );
            // IE fix (damn thing)
            baseNode.className = null;
        } else {
            var attrNode = getAttributeNode( baseNode, attributeName );
            //alert( "removing " + attributeName );
            if( attrNode != null ) {
                //alert( "removeAttributeNode" );
                baseNode.removeAttributeNode( attrNode );
                if( getAttributeNode( baseNode, attributeName ) != null ) {
                    //just to make sure it does not exist anymore
                    //alert( "removeAttribute" );
                    baseNode.removeAttribute( attributeName );
                    if( getAttributeNode( baseNode, attributeName ) != null ) {
                        //if everything fails...
                        //alert( "baseNode[ attributeName ]" );
                        baseNode[ attributeName ] = null;
                        //alert( "Success ? : " + (getAttributeNode( baseNode, attributeName ) == null)  );
                    }
                }
            }
        }
    }
};

function getAttributeNodeValue( baseNode, attributeName ) {
	var value = null;
	var attrNode = getAttributeNode( baseNode, attributeName );
	if( attrNode != null ) {
	    // should return its value
	    value = attrNode.value;

	    // but this damn simple thing seems not to work in many browser, as Defined in DOM Level 1
        if( value == null || value.length == 0 ) {

            // it gets even stranger cause, in some browser the attributeValues have to be access directly over there name...
            // but this can't work for every Node, HTMLInputElement has these 2 properties
            if( baseNode.nodeName.toLowerCase() == "input" ) {
                // grausig
                if( attributeName == "value" ) {
                    value = baseNode.value;
                }
                else
                if( attributeName == "name" ) {
                    value = baseNode.name;
                }
            }
        }
    }
	return value;
};


function hasAttribute( object, attributeName ) {
    var exists = false;
    if( object != null && attributeName != null ) {
        exists = typeof( object[ attributeName ] ) != "undefined";
    }
    return exists;
};

function isBoolean( value ) {
    return typeof( value ) == "boolean";
};

function getBooleanAttributeValue( object, attributeName ) {
    var asBoolean = false;
    if( hasAttribute( object, attributeName ) && isBoolean( object[ attributeName ] ) ) {
        asBoolean = toBoolean( object[ attributeName ] );

    }
    return asBoolean;
};

function toBoolean( someValue ) {
    var conversionResult = false;

    if( typeof( someValue ) == "undefined" ) {
        conversionResult = false;
    } else
    if( typeof( someValue ) == "null" || someValue == null ) {
        conversionResult = false;
    } else
    if( typeof( someValue ) == "boolean" ) {
        conversionResult = someValue;
    } else
    if( typeof( someValue ) == "number" ) {
        conversionResult = !(someValue == +0 || someValue == -0 || someValue == NaN);
    } else
    if( typeof( someValue ) == "string" ) {
        conversionResult = someValue.length > 0;
    } else
    if( typeof( someValue ) == "object" ) {
        conversionResult = true
    }

    return conversionResult;
};

function toNumber( someValue ) {
    var conversionResult = NaN;

    if( typeof( someValue ) == "undefined" ) {
        conversionResult = NaN;        
    } else
    if( typeof( someValue ) == "null" || someValue == null ) {
        conversionResult = +0;
    } else
    if( typeof( someValue ) == "boolean" ) {
        conversionResult = toBoolean( someValue ) == true ? 1 : +0;
    } else
    if( typeof( someValue ) == "number" ) {
        conversionResult = someValue;
    } else
    if( typeof( someValue ) == "string" ) {
        // todo
        //conversionResult = parseInt( someValue );
    } else
    if( typeof( someValue ) == "object" ) {
        // todo
    }


    return conversionResult;
};

function getFormNodeList( formNode, nodeNameList ) {
    var formNodeList = new Array();

    if( formNode != null && nodeNameList != null ) {

        for( var index=0; index < nodeNameList.length; index++ ) {

            var nextNodes = getNodesWithNameAndAttributeValue( formNode, FormNodeMetadata.ELEMENT_INPUT, "name", nodeNameList[ index ] );
            if( nextNodes == null || nextNodes.length == 0 ) {
                nextNodes = getNodesWithNameAndAttributeValue( formNode, FormNodeMetadata.ELEMENT_SELECT, "name", nodeNameList[ index ] );
            }
            if( nextNodes != null && nextNodes.length > 0 ) {
                formNodeList.push( new FormNode( nextNodes[ 0 ] ) );
            }
        }

        //alert( "Trying to fetch " + nodeNameList.length + " nodes, got :" + formNodeList.length );
    }

    return formNodeList;
};
