# Source: src/js/models/metadata/eml211/EMLOtherEntity.js

    define(["jquery", "underscore", "backbone", "models/metadata/eml211/EMLEntity"],
        function($, _, Backbone, EMLEntity) {

            /**
            * @class EMLOtherEntity
             * @classdesc EMLOtherEntity represents a generic data entity, corresponding
             * with the EML otherEntity module.
             * @classcategory Models/Metadata/EML211
             * @see https://eml.ecoinformatics.org/schema/eml-dataset_xsd.html#DatasetType_otherEntity
             * @extends EMLEntity
             */
            var EMLOtherEntity = EMLEntity.extend(
              /** @lends EMLOtherEntity.prototype */{

            	//The class name for this model
            	type: "EMLOtherEntity",

                /* Attributes of any entity */
                defaults: function(){
    	            return	_.extend({

    		                /* Attributes from EML */
                        entityType: "data entity",

    		                /* Attributes not from EML */
    		                nodeOrder: [ // The order of the top level XML element nodes
    		                    "alternateIdentifier",
    		                    "entityName",
    		                    "entityDescription",
    		                    "physical",
    		                    "coverage",
    		                    "methods",
    		                    "additionalInfo",
    		                    "attributeList",
    		                    "constraint",
    		                    "entityType"
    		                ],

    	            	}, EMLEntity.prototype.defaults());
                },

                /*
                 * The map of lower case to camel case node names
                 * needed to deal with parsing issues with $.parseHTML().
                 * Use this until we can figure out issues with $.parseXML().
                 */
                nodeNameMap: _.extend({
                    "entitytype": "entityType"

                }, EMLEntity.prototype.nodeNameMap),

                /* Initialize an EMLOtherEntity object */
                initialize: function(attributes) {

                    // if options.parse = true, Backbone will call parse()

                    // Call super() first
                    this.constructor.__super__.initialize.apply(this, [attributes]);

                    // EMLOtherEntity-specific work
                    this.set("type", "otherEntity", {silent: true});

                    // Register change events
                    this.on( "change:entityType", EMLEntity.trickleUpChange);

                },

                /*
                 * Parse the incoming other entity's XML elements
                 */
                parse: function(attributes, options) {

                    var attributes = attributes || {};

                    // Call super() first
                    attributes = this.constructor.__super__.parse.apply(this, [attributes, options]);

                    // EMLOtherEntity-specific work
                    var objectXML  = attributes.objectXML; // The otherEntity XML fragment
                    var objectDOM; // The W3C DOM of the object XML fragment
                    var $objectDOM; // The JQuery object of the XML fragment

                    // Use the updated objectDOM if we have it
                    if ( attributes.objectDOM ) {
                        $objectDOM = $(attributes.objectDOM);
                    } else {
                        // Hmm, oddly not there, start from scratch =/
                        $objectDOM = $(objectXML);
                    }

                    // Add the entityType
                    attributes.entityType = $objectDOM.children("entitytype").text();

                    return attributes;
                },

                /* Copy the original XML and update fields in a DOM object */
                updateDOM: function(objectDOM) {
                    var nodeToInsertAfter;
                    var type = this.get("type") || "otherEntity";
                    if ( ! objectDOM ) {
                        objectDOM = this.get("objectDOM");
                    }
                    var objectXML = this.get("objectXML");

                    // If present, use the cached DOM
                    if ( objectDOM ) {
                        objectDOM = objectDOM.cloneNode(true);

                    // otherwise, use the cached XML
                    } else if ( objectXML ){
                        objectDOM = $(objectXML)[0].cloneNode(true);

                    // This is new, create it
                    } else {
                        objectDOM = document.createElement(type);

                    }

                    // Now call the superclass
                    objectDOM = this.constructor.__super__.updateDOM.apply(this, [objectDOM]);

                    // And then update the EMLOtherEntity-specific fields
                    // Update the entityName
                    if ( this.get("entityType") ) {
                        if ( $(objectDOM).find("entityType").length ) {
                            $(objectDOM).find("entityType").text(this.get("entityType"));

                        } else {
                            nodeToInsertAfter = this.getEMLPosition(objectDOM, "entityType");

                            if ( ! nodeToInsertAfter ) {
                                $(objectDOM).append($(document.createElement("entitytype"))
                                    .text(this.get("entityType"))[0]);
                            } else {
                                $(nodeToInsertAfter).after($(document.createElement("entitytype"))
                                    .text(this.get("entityType"))[0]);
                            }
                        }
                    }

                    return objectDOM;
                },

                /*
                * Climbs up the model heirarchy until it finds the EML model
                *
                * @return {EML211 or false} - Returns the EML 211 Model or false if not found
                */
                getParentEML: function(){
                  var emlModel = this.get("parentModel"),
                      tries = 0;

                  while (emlModel.type !== "EML" && tries < 6){
                    emlModel = emlModel.get("parentModel");
                    tries++;
                  }

                  if( emlModel && emlModel.type == "EML")
                    return emlModel;
                  else
                    return false;

                },

                /* Serialize the EML DOM to XML */
                serialize: function() {

                    var xmlString = "";

                    // Update the superclass fields in the objectDOM first
                    var objectDOM = this.constructor.__super__.updateDOM.apply(this, []);

                    // Then update the subclass fields in the objectDOM
                    // TODO

                    this.set("objectXML", xmlString);

                    return xmlString;
                }

            });

            return EMLOtherEntity;
        }
    );