var SyncElement = new Class({
    Implements: [Class.Occlude],
    
    property: 'syncelement',
    
    initialize: function (element) {
        this.element = element;
        
        if (this.occlude()) {
            this.occluded.sync_properties = this.element.get('sync_properties').split(',').map(function (item, index, array) { return item.trim(); });
            
            return this.occluded;
        }
        
        this.sync_properties = this.element.get('sync_properties').split(',').map(function (item, index, array) { return item.trim(); });
        
        this._update_periodical = this.periodicalUpdate.periodical(250, this);
        
        this.sync();
        
        return this;
    },
    
    getTargetElement : function () {
        if (this.element.get('sync_from_ancestor') && (this.element.getParents(this.element.get('sync_from_ancestor')).length > 0)) {
            return this.element.getParents(this.element.get('sync_from_ancestor'))[0];
        }
        
        if (this.element.get('sync_from_descendant') && (this.element.getChildren(this.element.get('sync_from_descendant')).length > 0)) {
            return this.element.getChildren(this.element.get('sync_from_descendant'))[0];
        }
        
        if (this.element.get('sync_from_id') && $(this.element.get('sync_from_id'))) {
            return $(this.element.get('sync_from_id'));
        }
        
        return null;
    },
    
    periodicalUpdate : function () {
        if (this._target_data_json !== JSON.encode(this.getSyncData())) {
            this.sync();
        }
    },
    
    getSyncData : function () {
        var data, target_element;
        
        target_element = this.getTargetElement();
        
        data = target_element.getStyles.apply(target_element, this.sync_properties);
        
        if (this.sync_properties.contains('width')) {
            data.width  = target_element.getSize().x + 'px';
        }
        
        if (this.sync_properties.contains('height')) {
            data.height = target_element.getSize().y + 'px';
        }
        
        return data;
    },
    
    sync : function () {
        var target_element, sync_data;
        
        target_element = this.getTargetElement();
        
        sync_data = this.getSyncData();
        
        this._target_data_json = JSON.encode(sync_data);
        
        this.element.setStyles(sync_data);
    }
});

function activate_sync_elements(element) {
    element.getElements('.sync_element').each(function (sync_element) {
        new SyncElement(sync_element);
    });
}

window.element_activators.push(activate_sync_elements);


var StyleCopyElement = new Class({
    Implements: [Class.Occlude],
    
    property: 'stylecopyelement',
    
    initialize: function (element) {
        this.element = element;
        
        if (this.occlude()) {
            return this.occluded.occludedInitialize(element);
        }
        
        return this.occludedInitialize(element);
    },
    
    occludedInitialize: function () {
        var options, oldSetStyle;
        
        this.options = Object.clone({
            styles        : ['size'],
            childSelector : '.copy_destination'
        });
        
        if (this.element.get('stylecopyelementoptions')) {
            options = JSON.decode('{' + this.element.get('stylecopyelementoptions') + '}');
            
            Object.append(this.options, options);
        }
        
        oldSetStyle = this.element.setStyle;
        
        this.element.setStyle = function (property, value) {
            var destination_elements, size;
            
            oldSetStyle.bind(this.element)(property, value);
            
            if (this.options.styles.contains('size') && ['width', 'height'].contains(property)) {
                destination_elements = this.element.getElements(this.options.childSelector);
                
                size = this.element.getSize();
                
                destination_elements.each(function (destination_element) {
                    destination_element.setStyles({
                        'width'  : size.x + 'px',
                        'height' : size.y + 'px'
                    });
                    
                    destination_element.getElements('.multisizeimage').each(function (multisizeimage_element) {
                        multisizeimage_element.retrieve('multisizeimage').updateSize();
                    }.bind(this));
                }.bind(this));
            }
            else if (this.options.styles.contains(property)) {
                destination_elements = this.element.getElements(this.options.childSelector);
                
                destination_elements.each(function (destination_element) {
                    destination_element.setStyle(property, value);
                }.bind(this));
            }
        }.bind(this);
        
        return this;
    }
});

function activate_style_copy_elements(element) {
    element.getElements('.stylecopyelement').each(function (style_copy_element) {
        new StyleCopyElement(style_copy_element);
    });
}

window.element_activators.push(activate_style_copy_elements);

