/**
 * Class to represent Model objects, connected with Html elements
 * HtmlModel is child class of the Model
 * 
 * @returns {HtmlModel}
 */
function HtmlModel () {
    HtmlModel.superclass.constructor.apply(this, arguments);
    
    /**
     * Html of the object
     * 
     * @var JQuery private
     */
    var _html = null;
    
    /**
     * Reference to the Global objects data "data" property
     * @var Object private
     */
    var _data = this.set("data", {});
    
    /**
     * Sets or gets data for the named objects element
     * 
     * @param String name The name of the element
     * @param String|undefined data The data to be set
     * 
     * @return mixed Elements data, if the data parameter wasn't specified
     */
    this.val = function (name, data) {
    	//check if there is such element with specified "name" in the object
        if (name in _data){    
            if (typeof(data) != 'undefined'){
            	//setting the data to the element
                _data[name].set(name, data);
                //if element was hidden or there is block for adding one more
                //such element, make these blocks visible
                if ('hidden' in _data[name] && data){
                    _data[name].find.removeClass('hidden-object');
                    if ('addFind' in _data[name]){
                        _data[name].addFind.removeClass('hidden-object');
                    }
                }
            } else {
            	//just return the value of the element
                return  _data[name].get(name);
            }
        } else{
            this.addError('html_model', 'val not found data: ' + name);
            //this.addError('constructor', this.constructor + '' );
        }
        return false;
    };
    
    /**
     * Checks if object with "name" key exists in HtmlModel _data
     * 
     * @param String name Data key
     * @return Boolean "true" if there is such key, "false" otherwise
     */
    this.isset = function(name) {
        if (name in _data) {
            return true;
        } else {
            return false;
        }
    };
    
    /**
     * Fetches objects _html property
     * 
     * @return String _html property
     */
    this.html = function(){
        return _html;
    };
    
    /**
     * Inits object with predefined settings and data
     * predefined settings haev the folliwing format
     * data = {html: ..., elem: []}
     * html - html for the Object, will be stored in _html property
     * elem - array of elements to be added to the object. @see addElement for element format
     * elements are parts of the current object. for example Article html
     * model object has title, data, teaser, bosy elements.
     * 
     * @param Object data Settings for initializing the object
     * @returns Boolean "true" if the initialization was successfull, "false" otherwise
     */
    this.init = function(data){
    	
    	//Set the _html property. data.html is a required parameter
        if ('html' in data){
            _html = this.set("html",  data.html);
        }else{
            this.addError('html_model', 'data.html required param');
            return false;
        }
        
        //adding elements to the objects
        if ('elem' in data){
            for (var a in data.elem){
                addElement(data.elem[a]);
            }
        }
        
        return true;
    };
    
    /**
     * Adds element to the current object
     * elem parameter has the following format
     * elem = {name: ..., }
     * 
     * @param Object elem Element to be added to the data
     * @returns
     */
    var addElement = function (elem) {
    	
    	//set element name. name property is required parameter
        if ('name' in elem) {
            _data[elem.name] = {};
        } else {
             this.addError('html_model', 'elem.name required param');
             return false;
        }
        
        //find the element in _html code of the object
        if ('find' in elem){
            _data[elem.name].find = _html.find(elem.find);
        } else {
             this.addError('html_model', 'elem.find required param');
             return false;
        }
        
        //find the htmlcode which is responsible for adding such element to the html model object
        if ('addFind' in elem){
            _data[elem.name].addFind = _html.find(elem.addFind);
        }
        
        //element tagName
        var tagName = _data[elem.name].find.attr('tagName');

        //specifying the get() and set() methods for the element
        //depending on element html tagName set() and get() methods specify
        //element text, href or src attributes
        if (tagName.toUpperCase() in {'SPAN':1, 'DIV':1, 'H1':1, 'H2':1, 'H3':1, 'H4':1, 'H5':1, 'H6':1}) {
            _data[elem.name].set = function (name, data) {                
                _data[name].find.text(data);
            };
            
            _data[elem.name].get = function (name) {
                return _data[name].find.text();
            };
        }
        
        if (tagName.toUpperCase() == 'A') {
            _data[elem.name].set = function (name, data) {
                data = (data === false) ? '' : data; 
                _data[name].find.attr('href', data);
            };
            
            _data[elem.name].get = function (name){
                return _data[name].find.attr('href');
            };
        }
        
        if (tagName.toUpperCase() == 'IMG') {
            
            _data[elem.name].set = function (name, data) {
                _data[name].find.attr('src', data);
            };
            
            _data[elem.name].get = function (name) {
                return _data[name].find.attr('src');
            };
        }
        
        if ('hidden' in elem){
            _data[elem.name].hidden = true;
        }
        
        return true;
    };
}

//Making HtmlModel child class of the Model
extend(HtmlModel, Model);
