var Layout = Class.extend({
	init: function(template, data)
	{
		this.parent = null;
		this.parents = [];
		this.id = 0;
		this.name = '';
		this.locked = false;
		this.linked = true;
		this.css = '';
		this.position = 0;
		this.breakpoints = [];
		this.children = [];
		this.item = null;
		this.items = [];
		this.template = null;
		this.html = '';
		this.predefined = false;
		this.updated = false;
		this.blocked = true;
		this.tmpId = this.generateTmpId();
		this.startDate = null;
		this.endDate = null;
		this.linkedToPage = false;

		if (typeof(template) != "undefined") {
			this.template = template;
		}
		if (typeof(data) != "undefined") {
			this.load(data);
		}
		this.template
			.addLayoutInfo(null, this);
	},
	generateTmpId: function()
	{
		var date = new Date();
		return Layout.TMP_ID+date.getTime()+''+(
			Math.random()*100
		);
	},
	getTarget: function()
	{
		if (!this.item && this.items.length > 0) {
			this.item = this.items[0];
		}

		return this.item;
	},
	getTargets: function()
	{
		return this.items;
	},
	selectTarget: function(item)
	{
		var $this = this;

		if ($this.items.indexOf(item) >= 0) {
			$this.item = $this.items[
				$this.items.indexOf(item)
			];
		}

		return $this.item;
	},
	addTarget: function(item)
	{
		this.items.push(item);
		if (!this.item) {
			this.item = item;
		}
	},
	removeTarget: function(item)
	{
		var $this = this;

		if ($this.item.get(0) == item.get(0)) {
			$this.detachTarget(item, $this.items.indexOf($this.item));
			$this.item = null;
		} else {
			jQuery.each($this.items, function(index, target){
				var found = false;

				if (target.get(0) == item.get(0)) {
					$this.detachTarget(item, index);
					found = true;
				}

				return !found;
			});
		}
	},
	detachTarget: function(item, index)
	{
		this.items.splice(index, 1);
		jQuery(Layout.TAG, item).each(function(){
			jQuery(this).data('object').removeTarget(jQuery(this));
		});
	},
	resetTargets: function()
	{
		this.items = [];
	},
	load: function(data)
	{
		var layoutPage, $this = this;

		try {
			if (typeof(data) == "string") {
				data = jQuery.parseJSON(data);
			}

			$this.id = data.id;
			$this.name = data.name;
			$this.predefined = ($this.id > 0 && data.predefined);
			$this.locked = data.locked;
			$this.linked = data.linked;
			$this.css = data.css;
			$this.position = data.position;

			jQuery.each(data.layoutPages, function(index, layoutPageAux){
				var found = false;

				if (layoutPageAux.page == $this.template.page) {
					layoutPage = layoutPageAux;
					$this.linkedToPage = (layoutPageAux.page != null);
					found = true;
				} else if (!layoutPageAux.page && !layoutPage) {
					layoutPage = layoutPageAux;
				}

				return !found;
			});
			if (layoutPage) {

				$this.startDate = layoutPage.startAt !== null ? moment(layoutPage.startAt.date).format('YYYY-MM-DD HH:mm') : null;
				$this.endDate = layoutPage.endAt !== null ? moment(layoutPage.endAt.date).format('YYYY-MM-DD HH:mm') : null;

	            if(layoutPage.layoutPageWidgets.length > 0) {
	                for(var widget in layoutPage.layoutPageWidgets) {
	                	if (!$this.linkedToPage && !$this.linked) {
	                		layoutPage.layoutPageWidgets[widget].id = null;
	                	}
	                    var widgetObject = new Widget(null, $this, layoutPage.layoutPageWidgets[widget]);
	                    $this.template.widgetsStorage.add(widgetObject);
	                    CSWidgetQueue.enqueue(widgetObject);
	                }
	            }
			}

			if (typeof(data.html) != "undefined") {
				$this.html = data.html;
			}

			$this.breakpoints = {};
			jQuery.each(data.layoutBreakpoints, function(index, breakpointData){
				var layoutBreakpoint = new LayoutBreakpoint(breakpointData);
				layoutBreakpoint.columns = Math.round(
					$this.template.columns*(layoutBreakpoint.columns/100)
				);
				$this.breakpoints[layoutBreakpoint.type] = layoutBreakpoint;
			});/*
			jQuery.each($this.template.breakpoints, function(index, breakpoint){
				if (typeof($this.breakpoints[breakpoint.type]) == "undefined") {
					$this.breakpoints[breakpoint.type] = new LayoutBreakpoint({
						type: breakpoint.type,
						visibility: false
					});
				}
			});*/
			$this.children = [];
			jQuery.each(data.children, function(index, layoutData){
				var layout = new Layout($this.template, layoutData);
				layout.parent = $this;
				$this.children.push(layout);
			});
			jQuery.each(data.layouts, function(index, layoutData){
				var layout = new Layout($this.template, layoutData);
				$this.children.push(layout);
			});
			$this.template
				.addLayoutInfo(data, $this);
		} catch(error) {throw error;}
	},
	render: function()
	{
		var value, $this = this;

		if ($this.getTargets().length == 0) {
			if ($this.id) {
				jQuery(
					Layout.TAG+'#'+$this.id,
					$this.template.getTarget()
				).each(function(){
					$this.addTarget(jQuery(this));
				});
			} else {
				jQuery(
					Layout.TAG+'[tmpId="'+$this.tmpId+'"]',
					$this.template.getTarget()
				).each(function(){
					$this.addTarget(jQuery(this));
				});
			}
		}
		if ($this.getTargets().length > 0) {
			if ($this.parent || !$this.predefined) {
				$this.blocked = false;
			}
			$this.defineAttributes();
			$this.enable(true);
			if ($this.children) {
				jQuery.each($this.children, function(index, layout){
					layout.render();
				});
			}
            if($this.template.mode === Template.CONTENT_MODE) {
                $this.enableContentMode();
            }
		} else {
			$this.remove();
		}
	},
	update: function(changed)
	{
		if (changed && !this.updated) {
			this.updated = true;
			/*jQuery.each(this.children, function(index, layout){
				layout.update(changed);
			});*/
			if (this.getParent()) {
				this.getParent().update(changed);
			} else {
				this.template.update(changed);
			}
		}
	},
	resetUpdate: function()
	{
		jQuery.each(this.children, function(index, layout){
			layout.resetUpdate();
		});
		this.updated = false;
	},
	resetChildren: function()
	{
		this.children = [];
	},
	block: function()
	{
		var $this = this;

		jQuery.each(this.getTargets(), function(index, target) {
			target.addClass(Layout.BLOCKED_CLASS);
			target.off('click').click(function(event){
				event.preventDefault();

				modal = new Modal();
				modal.render();
				modal.addContent(Translator.trans(
					'cs_admin.designer.modal.infoModifyLinked'
				));
				modal.addOption(
					Modal.YES_OPTION,
					Translator.trans(
						'cs_admin.designer.modal.acceptModifyLinked'
					),
					Translator.trans(
						'cs_admin.designer.modal.modifyLinked'
					),
					null,
					function(event){
						event.preventDefault();

						$this.unblock();
						$this.enable();
						modal.remove();
					}
				);
				modal.addOption(
					Modal.NO_OPTION,
					Translator.trans(
						'cs_admin.designer.modal.declineModifyLinked'
					),
					Translator.trans(
						'cs_admin.designer.modal.duplicateLinked'
					),
					null,
					function(event){
						var item;

						event.preventDefault();

						item = $this.duplicate(target);
						item.unblock();
						item.enable();
						modal.remove();
					}
				);
				$this.template.getTarget().append(
					modal.getTarget()
				);
				modal.show(null, true);
			});
		});
	},
	unblock: function(onlyClass)
	{
		jQuery.each(this.getTargets(), function(index, target) {
			target.removeClass(
				Layout.BLOCKED_CLASS
			).off('click');
		});
		if (!onlyClass) {
			this.blocked = false;
			this.template.enableResizable();
		}
		jQuery.each(this.children, function(index, layout){
			layout.unblock(onlyClass);
		});
	},
	duplicate: function(target)
	{
		var layout = new Layout(
			this.template
		);
		this.removeTarget(target);
		target.removeAttr('id');
		target.attr('linked', false);
		layout.parent = this.parent;
		layout.defineAttributes(target);

		layout.predefined = false;
		layout.update(true);
		jQuery.each(this.children, function(index, child){
			var item = child.duplicate(
				jQuery('#'+child.id, target)
			);
			item.parent = layout;
			layout.children.push(item);
		});

		return layout;
	},
	enable: function(withoutChildren)
	{
		var modal, $this = this;

		if ($this.blocked && !$this.parent) {
			$this.block();
		} else {
			$this.unblock(true);
		}
		jQuery.each(this.getTargets(), function(index, target) {
			target.off("mouseenter mouseleave");
			target.attr('tmpId', $this.tmpId);
			if ($this.blocked) {
				if (!$this.parent) {
					target.hover(function(){
						$this.selectTarget(target);
						$this.showToolbar();
					}, function(){
						$this.hideToolbar();
					});
				}
			} else {
				target.hover(function(){
					$this.selectTarget(target);
					if (!$this.template.getTarget().data('resizing')) {
						jQuery(this).addClass('select-hover');
						$this.showToolbar();
						if ($this.name != '') {
							$this.getTarget()
								.children('.'+Layout.NAME_CLASS)
								.show();
						}
					}
				}, function(){
					if (!$this.template.getTarget().data('resizing')) {
						jQuery(this).removeClass('select-hover');
						$this.hideToolbar();
						if ($this.name != '') {
							$this.getTarget()
								.children('.'+Layout.NAME_CLASS)
								.hide();
						}
					}
				});

                $this.getEditableZone().CSDroppable('enable');

                target.CSDraggable({
                    helper: 'move',
                    dragstart: function(){
                        jQuery.CSDragAndDropStore.customData['non-droppable-layouts'] = $this.getAllChildrenIds();
                    }
                });

				//jQuery('.'+Layout.CONTENT_CLASS, target)
                $this.getEditableZone().addClass(Template.EDITABLE_CLASS);

				if (target.children('.'+Layout.NAME_CLASS).length == 0) {
					target.append(jQuery('<span/>', {
						class: Layout.NAME_CLASS,
						text: $this.name,
						click: function(event){
							var item, value;

							event.preventDefault();

							if (!jQuery(this).hasClass(Layout.EDIT_CLASS)) {
								jQuery(this).addClass(Layout.EDIT_CLASS);
								$this.template.disable(false, true);

								value = jQuery(this).text();
								item = jQuery('<input/>', {
									type: 'text',
									blur: function(event){
										event.preventDefault();

										$this.update($this.name != jQuery(this).val());
										$this.name = jQuery(this).val();
										if ($this.name == '') {
											$this.save(false);
											$this.showToolbar();
										}
										jQuery.each($this.getTargets(), function(index, targetItem) {
											if ($this.name == '') {
												targetItem.children('.'+Layout.NAME_CLASS)
													.hide();
											}

											targetItem.attr('name', $this.name);
											targetItem.children('.'+Layout.NAME_CLASS)
												.text($this.name)
												.removeClass(Layout.EDIT_CLASS);
										});
										$this.template.enable();
									},
									keyup: function(event){
										if(event && event.which == 13){
											event.preventDefault();
											jQuery(this).blur();
										}
									}
								});
								jQuery(this).html(
									jQuery('<span/>', {
										class: Layout.EDIT_CLASS
									}).html(item)
								);
								item.focus().val(value);
							}
						}
					}).hide());
				}
			}
		});

		if (!withoutChildren) {
			jQuery.each($this.children, function(index, layout){
				layout.enable();
			});
		}
	},
	disable: function(lock)
	{
		this.unblock(true);
		jQuery.each(this.children, function(index, layout){
			layout.disable(lock);
		});
		jQuery.each(this.getTargets(), function(index, target) {
			target.off("mouseenter mouseleave");
			target.removeAttr('tmpId');
			target.removeClass('select-hover');
			target.data('object').getEditableZone().CSDroppable('destroy');
			target.CSDraggable('destroy');

			jQuery('.'+Layout.CONTENT_CLASS, target)
				.removeClass(Template.EDITABLE_CLASS);

			if (!lock && target.children('.'+Layout.NAME_CLASS).length > 0) {
				target.children('.'+Layout.NAME_CLASS).remove();
			}
		});
	},
	addLayout: function(item, render, force, onlyCurrentTarget)
	{
		var excluded, layout, $this = this;

		if (item.children(Layout.TAG).length > 0) {
			item = item.children(Layout.TAG);
		}
		if (item.attr('id') || item.attr('tmpId')) {
			layout = $this.template
				.getLayoutObject(
					item.attr('id') ? item.attr('id') : item.attr('tmpId')
				);
		}
		if (layout) {
			if (force) {
				$this.children.push(layout);
				if (item.html() != '' || layout.children.length == 0) {
					layout.html = item.html();
				}
			}
			layout.defineAttributes(item, true);
			item.find(Layout.TAG).each(function(){
				if (
					jQuery(this).parentsUntil(
						item, Layout.TAG
					).length == 0
				) {
					layout.addLayout(
						jQuery(this), false, force, true
					);
				}
			});
		} else {
			layout = new Layout($this.template);
			layout.parent = $this;
			$this.children.push(layout);
			layout.defineAttributes(item);
			if (!layout.id || force) {
				item.find(Layout.TAG).each(function(){
					if (
						jQuery(this).parentsUntil(
							item, Layout.TAG
						).length == 0
					) {
						layout.addLayout(
							jQuery(this), false, force, true
						);
					}
				});
			}
		}

		if ($this.predefined) {
			layout.predefined = $this.predefined;
			if (!item.attr('linked')) {
				layout.linked = $this.linked;
			}
			layout.defineAttributes();
		}
		layout.enable();
		if (!onlyCurrentTarget) {
			jQuery.each($this.getTargets(), function(index, target) {
				if ($this.getTarget().get(0) != target.get(0)) {
					target.html($this.getTarget().html());

					target.find(Layout.TAG).each(function(){
						var tmpId = jQuery(this).attr('tmpId');
						var child = $this.template
							.getLayoutObject(tmpId);
						if (child) {
							child.addTarget(jQuery(this));
							child.defineAttributes();
							child.enable();
						}
					});
				}
			});
		}
		$this.html = $this.getTarget().html();

		if (render) {
			layout.render();
		}
		$this.update(true);
		$this.template
			.cleanRemovedLayout($this);

		return layout;
	},
	defineAttributes: function(item, loaded)
	{
		var id, breakpoints, $this = this;

		if (item) {
			$this.addTarget(item);
			if (!loaded) {
				if ($this.html != '') {
					if ($this.children && item.is(':empty')) {
						item.html($this.html);
					}
				} else if (item.attr('id') && !isNaN(parseInt(item.attr('id'), 10))) {
					if (
						$this.template.getLayoutInfo(
							item.attr('id')
						)
					) {
						$this.load(
							$this.template.getLayoutInfo(
								item.attr('id')
							)
						);
					} else {
						jQuery.ajax({
							async: false,
							url: Routing.generate(
								'cs_core_designer_generate_json_layout',
								{
									layoutId: item.attr('id')
								},
								true
							),
							success: function(data){
								$this.load(data);
							}
						});
					}
				}
			}
			if (item.attr('class')) {
				breakpoints = $this.template.extractBreakpoints(
					item.attr('class').split(' ')
				);
				jQuery.each(breakpoints, function(type, value) {
					if (typeof($this.breakpoints[type]) != "undefined") {
						breakpoint = $this.breakpoints[type];
					} else {
						breakpoint = new LayoutBreakpoint();
						breakpoint.type = type;
					}
					breakpoint.visibility = false;
					if (value) {
						breakpoint.visibility = true;
						breakpoint.columns = value;
					}
					breakpoints[type] = breakpoint;
				});
				$this.breakpoints = breakpoints;
			}
			if (item.attr('locked')) {
				$this.locked = $this.parseBool(
					item.attr('locked').toLowerCase()
				);
			}
			if (item.attr('name')) {
				$this.name = item.attr('name');
			}
			if (item.attr('linked')) {
				$this.linked = $this.parseBool(
					item.attr('linked').toLowerCase()
				);
			}
			if (item.attr('style')) {
				$this.css = item.attr('style');
			}
			if (item.attr('predefined') && !$this.id) {
				$this.predefined = $this.parseBool(
					item.attr('predefined').toLowerCase()
				);
			}
		} else {
			jQuery.each($this.getTargets(), function(index, target) {
				target.data('object', $this);
				jQuery.each($this.breakpoints, function(index, breakpoint){
					breakpoint.addClass(target);
				});
				target.attr('locked', $this.locked);
				target.attr('linked', $this.linked);
				if ($this.css) {
					target.attr('style', $this.css);
				}
				if ($this.id) {
					target.attr('id', $this.id);
				} else if ($this.predefined) {
					target.attr('predefined', $this.predefined);
				}

				if ($this.children && $this.html != '' && target.is(':empty')) {
					target.html($this.html);
				}
			});
		}
		if ($this.name == '') {
			$this.name = Translator.trans(
				'cs_admin.designer.layouts.defaultName', {
					count: (
						$this.id ? $this.id : $this.template.getCountLayouts()
					)
				}
			);
		}
		jQuery.each($this.getTargets(), function(index, target) {
			if ($this.name) {
				target.attr('name', $this.name);
			}
            $this.getEditableZone().CSDroppable({
				drop: $this.template.dropCallback,
				dragover: $this.template.dragOverCallback,
				excludedSelectors: Template.DROPPABLE_EXCLUDED_SELECTORS
			});
			target.CSDraggable({
				helper: 'move',
				dragstart: function(){
					jQuery.CSDragAndDropStore.customData['non-droppable-layouts'] = $this.getAllChildrenIds();
				}
			});
			if ($this.blocked) {
                $this.getEditableZone().CSDroppable('disable');
			}
		});
	},
	resize: function(finished)
	{
		var width, currentClass, newClass, breakpoint, $this = this;

		if (finished) {
			switch ($this.getTarget().data('resize-type')) {
				case Template.RESIZE_HEIGHT:
					if (
						$this.getTarget().data('sizes').originalHeight != '' ||
						$this.getTarget().outerHeight() != $this.getTarget().data('sizes').height
					) {
						$this.getToolbar().cleanHeight(
							($this.getTarget().css('height') != '')
						);
					} else {
						$this.getTarget().css('height', '');
					}
					$this.getTarget().css('width', '');
					if ($this.getTarget().attr('style')) {
						$this.css = $this.getTarget().attr('style');
					} else {
						$this.css = '';
					}
					break;
				case Template.RESIZE_WIDTH:
					width = (
						$this.getTarget().width()/$this.getTarget().parent().width()
					);
					breakpoint = $this.getBreakpoint(
						$this.template.currentBreakpoint
					);
					currentClass = breakpoint.columnsClass();
					breakpoint.columns = Math.max(
						1, Math.round(CSTemplate.columns*width)
					);
					newClass = breakpoint.columnsClass();
					jQuery.each($this.getTargets(), function(index, target) {
						target.removeClass(currentClass);
						target.addClass(newClass);
					});
					break;
			}
			jQuery.each($this.getTargets(), function(index, target) {
				target.attr('style', $this.css);
			});
			$this.update(true);
			jQuery(
				'.'+Layout.RESIZE_CLASS, $this.getTarget()
			).remove();
		} else {
			$this.getTarget().append(jQuery(
				'<div/>',
				{
					'class': Layout.RESIZE_CLASS
				}
			));
			$this.getTarget().data('sizes', {
				'width': $this.getTarget().outerWidth(),
				'height': $this.getTarget().outerHeight(),
				'originalHeight': $this.getTarget().prop('style').height
			});
			$this.getTarget().data(
				'padding-width',
				$this.getTarget().outerWidth()-$this.getTarget().width()
			);
			$this.getTarget().data(
				'padding-height',
				$this.getTarget().outerHeight()-$this.getTarget().height()
			);
			$this.updateSizes();
		}
	},
	updateSizes: function(sizes)
	{
		var width, height, breakpoint, columns;

		if (jQuery(
			'.'+Layout.RESIZE_CLASS, this.getTarget()
		).length > 0) {
			if (sizes) {
				width = this.getTarget().data('sizes').width;
				if (width != sizes.width) {
					sizes.width += this.getTarget().data('padding-width');
				}
				height = this.getTarget().data('sizes').height;
				if (height != sizes.height) {
					sizes.height += this.getTarget().data('padding-height');
				}
			} else {
				sizes = this.getTarget().data('sizes');
			}
			height = sizes.height;
			width = Math.round((sizes.width*100)/
						this.getTarget().parent().width());

            breakpoint = this.getBreakpoint(
                this.template.currentBreakpoint
            );


            columns = Math.max(
                1, Math.round(CSTemplate.columns*(sizes.width/this.getTarget().parent().width()))
            );

			jQuery(
				'.'+Layout.RESIZE_CLASS, this.getTarget()
			).html(jQuery('<span/>', {
				html: Translator.trans('cs_admin.designer.layouts.resize_placeholder', {'width' : width, 'height': height, 'columns': columns})
			}));
		}
	},
	getBreakpoint: function(type)
	{
		if (typeof(this.breakpoints[type]) == "undefined") {
			breakpoint = new LayoutBreakpoint();
			breakpoint.type = type;
			breakpoint.visibility = true;
			breakpoint.columns = this.template.columns;
			this.breakpoints[type] = breakpoint;
		} else {
			breakpoint = this.breakpoints[type];
		}

		return breakpoint;
	},
	getToolbar: function(check)
	{
		return this.template.getToolbar(check);
	},
	showToolbar: function()
	{
		var breakpoint = this.getBreakpoint(this.template.currentBreakpoint);
		var toolbar = this.getToolbar();
		var parent = this.getParent();
        var removeFunction = function(event){
            var element = toolbar.getElement(),
                parent = element.getTarget().closest('.'+Layout.ROW_CLASS),
                widgets = $(Widget.TAG, element.getTarget());

            $.each(widgets, function() {
                if(typeof $(this).data('object') !== 'undefined') {
                    $(this).data('object').remove();
                } else {
                    $(this).remove();
                }

            });

            element.remove();

            if(parent.is(':empty')) {
                parent.remove();
            }
        };

		toolbar.render(this);
		if (!this.parent && this.blocked) {
			toolbar.edit(true, function(event){
				toolbar.getElement()
					.getTarget().click();
			});
			toolbar.remove(true, removeFunction, true);
		} else {
			toolbar.visibility(true, breakpoint.visibility, function(event){
				toolbar.getElement().visibility();
			});
			toolbar.lock(true, this.locked, function(event){
				toolbar.getElement().lock();
			});
			if (this.children.length == 0) {
				toolbar.link(
					true,
					this.linked,
					function(event){
						toolbar.getElement().link();
					}
				);
			}
			toolbar.css(true, function(event){
				toolbar.getElement().style();
			});
			toolbar.cleanHeight((this.getTarget().get(0).style.height != ''), function(event){
				var item = toolbar.getElement().getTarget();
				var minHeight = 0;
				item.children().each(function(){
					if (!jQuery(this).hasClass('ui-resizable-handle')) {
						minHeight += jQuery(this).outerHeight(true);
					}
				});
				item.animate({
					height: minHeight+(item.outerHeight()-item.height())
				}, 'slow', function(){
					jQuery.each(toolbar.getElement().getTargets(), function(index, target) {
						target.css('height', '');
						if (typeof(target.attr('style')) != "undefined") {
							toolbar.getElement().css = target.attr('style');
						} else {
							toolbar.getElement().css = '';
						}
					});
					toolbar.cleanHeight(false);
					toolbar.getElement().update(true);
				});
			});
			toolbar.save(
				!parent || !parent.predefined,
				this.predefined,
				function(event){
					toolbar.getElement().save();
				}
			);
			toolbar.remove(true, removeFunction);
		}
	},
	hideToolbar: function()
	{
		var toolbar;

		if (this.getToolbar(true)) {
			toolbar = this.getToolbar();
			toolbar.reset(this);
		}
	},
    showContentToolbar: function()
    {
        var toolbar = this.getToolbar(),
            $this = this;
        toolbar.reset(this);
        toolbar.render(this);

        var editDatesCallback = ContentManager.prototype.editDatesCallback(this);
        toolbar.editDates(true, editDatesCallback);

        if($this.template.allWidgetsLoaded) {
            toolbar.copy(true, function() {
                $this.template.keyboardShortcutsManager._copy($this.getTarget());
            });

            toolbar.cut(true, function() {
                $this.template.keyboardShortcutsManager._cut($this.getTarget());
            });

            toolbar.paste(true, function() {
                $this.template.keyboardShortcutsManager._paste($this.getTarget());
            });
        }
    },
    enableContentMode: function()
    {
        var target = this.getTarget();
        var startDate = new Date(this.startDate);
        var endDate = new Date(this.endDate);

        target.removeClass(
        	ContentManager.FUTURE_ELEMENT_CLASS+
        	' '+ContentManager.PAST_ELEMENT_CLASS
        );
        if(this.startDate && startDate > new Date()) {
            target.addClass(ContentManager.FUTURE_ELEMENT_CLASS);
        } else if(this.endDate && endDate < new Date()){
            target.addClass(ContentManager.PAST_ELEMENT_CLASS);
        }
    },
    enableContentToolbar: function()
    {
        var $this = this;
        var target = $this.getTarget();
        target.off("mouseenter mouseleave");

        target.hover(function (event) {
            event.stopPropagation();
            $this.showContentToolbar();
        }, function (event) {
            event.stopPropagation();
            $this.hideToolbar();
            $this.template.removeToolbar();
        });
    },
	generateItem: function(className)
	{
		var item = jQuery('<'+Layout.TAG+'/>');
		if (className) {
			item.addClass(className);
		}
		item.html(jQuery('<div/>', {
			'class': Layout.CONTENT_CLASS
		}));

		return item;
	},
	addRow: function()
	{
		jQuery.each($this.getTargets(), function(index, target) {
			jQuery('.'+Layout.CONTENT_CLASS, target).html(
				jQuery('<div/>', {
					'class': Layout.ROW_CLASS
				})
			);
		});
	},
	visibility: function(type)
	{
		var breakpoint;

		if (!type) {
			type = this.template.currentBreakpoint;
		}
		breakpoint = this.getBreakpoint(type);
		jQuery.each(this.getTargets(), function(index, target) {
			breakpoint.changeVisibility(target);
		});
		this.update(true);
	},
	lock: function(value)
	{
		var $this = this;

		if (!value) {
			value = !$this.locked;
		}
		$this.locked = value;
		/*jQuery.each($this.children, function(index, layout){
			if (!layout.predefined) {
				layout.lock(value);
			}
		});*/
		jQuery.each($this.getTargets(), function(index, target) {
			target.attr('locked', $this.locked);
		});
		$this.update(true);
	},
	link: function(value)
	{
		var $this = this;

		if (!value) {
			value = !$this.linked;
		}
		$this.linked = value;
		jQuery.each($this.children, function(index, layout){
			layout.link(value);
		});
		jQuery.each($this.getTargets(), function(index, target) {
			target.attr('linked', $this.linked);
		});
		$this.update(true);
	},
	style: function()
	{
		var modal, item, $this = this;

		if (
			$this.getTarget()
				.children('span.'+Layout.EDIT_CLASS)
				.length == 0
		) {
			item = jQuery('<textarea/>', {
				blur: function(event){
					var value, node;

					event.preventDefault();

					$this.update($this.css != jQuery(this).val());
					$this.css = jQuery(this).val();
					jQuery.each($this.getTargets(), function(index, target) {
						target.attr('style', $this.css);
					});
					modal.remove();
					$this.enable();
				}
			});
			item.enableSelection();

			modal = new Modal();
			modal.render(Layout.STYLES_CLASS);
			modal.addContent(item);
			modal.addOption(
				Modal.ACCEPT_OPTION,
				'<strong>'+
				Translator.trans(
					'cs_admin.designer.modal.accept'
				)+
				'</strong>',
				null,
				null,
				function(event){
					event.preventDefault();
					item.blur();
				}
			);
			$this.getTarget().append(
				modal.getTarget()
			);
			modal.allowCancel();
			modal.show(function(){
				$this.disable();
				item.focus().val($this.css);
			}, true);
		}
	},
	save: function(value)
	{
		if (!value) {
			value = !this.predefined;
			this.link(value);
			this.getToolbar()
				.link(value, this.linked);
			if (this.name == '' && value)  {
				this.getTarget()
					.children('.'+Layout.NAME_CLASS)
					.show().focus();
				this.getTarget()
					.children('.'+Layout.NAME_CLASS).click();
			}
		}
		this.predefined = value;
		jQuery.each(this.children, function(index, layout){
			layout.save(value);
		});
		this.update(true);
	},
	remove: function()
	{
		var $this = this;
		var item = $this.getParent();

		$this.hideToolbar();
		if (!item) {
			if ($this.getTargets().length > 0) {
				item = $this.getTarget();
				$this.removeTarget($this.getTarget());
				item.hide();
				item.remove();
			}
		} else {
			jQuery.each($this.getTargets(), function(index, target) {
				target.hide();
				target.remove();
			});
			$this.resetTargets();
			item.removeChild($this);
		}
		if ($this.getTargets().length == 0) {
			$this.template.removeLayout($this, true);
		}
		$this.update(true);
	},
	getParent: function(update)
	{
		var item = this.parent;

		if (update) {
			item = this.getTarget()
				.parents(Layout.TAG+':first');
			item = ((item.length > 0) ? item.data('object') : null);
		}

		return item;
	},
	updateParent: function()
	{
		var currentParents, addedInTemplate, $this = this;
		var previous = this.getParent();
		var current = this.getParent(true);

		if ($this.predefined) {
			currentParents = [];
			addedInTemplate = false;
			jQuery.each($this.getTargets(), function(index, target) {
				var item = target.parents(Layout.TAG+':first');
				if (item.length > 0) {
					currentParents.push(
						item.data('object').tmpId
					);
				} else {
					addedInTemplate = true;
				}
			});
			jQuery.each($this.parents, function(index, item) {
				var exists = currentParents.indexOf(
					item.tmpId
				);
				if (exists < 0) {
					item.removeChild($this);
					$this.parents.splice(index, 1);
				}
			});
			$this.template.removeLayout($this);
			if (addedInTemplate) {
				$this.template
					.layouts.push($this);
			}
			$this.template.getTarget()
			if (current) {
				if (
					$this.parents.indexOf(
						current
					) < 0
				) {
					$this.parents.push(current);
					current.children.push($this);
				}
			}
		} else if (previous != current) {
			$this.parent = current;
			if (!previous) {
				$this.template.removeLayout($this);
			} else {
				previous.removeChild($this);
			}
			if (current) {
				current.children.push($this);
			} else {
				$this.template
					.layouts.push($this);
			}
			$this.refreshCss();
			$this.update(true);
		}
	},
	removeChild: function(child)
	{
		var index = this.children.indexOf(child);
		if (index >= 0) {
			this.children.splice(index, 1);
			//this.removeTarget(child.getTarget());
		}
		this.update(true);
	},
	export: function()
	{
		var item = {};
		var $this = this;
		var date = new Date();

		item.id = this.id;
		if (item.id <= 0) {
			item.tmpId = this.tmpId;
			this.getTarget().attr('id', item.tmpId);
		}

		item.parent = null;
		if (this.parent) {
			item.parent = {
				id: this.parent.id
			}
		}
		item.name = this.name;
		item.locked = this.locked;
		item.predefined = this.predefined;
		item.linked = (this.linked || (this.predefined && this.children.length > 0));
		item.css = this.css;
		item.layoutBreakpoints = [];
		jQuery.each(this.breakpoints, function(index, breakpoint){
			var data;

			if (breakpoint) {
				data = breakpoint.export();
				data.columns = ((data.columns*100)/$this.template.columns);
				breakpoint = $this.template.getBreakpoint(
					data.breakpoint
				);
				data.breakpoint = breakpoint.export();

				item.layoutBreakpoints.push(data);
			}
		});
		item.predefined = this.predefined;
		item.updated = this.updated;
		this.refreshCss();

		item.children = [];
		item.layouts = [];
		jQuery.each(this.children, function(index, layout){
			if (layout) {
				var element = layout.export();
				if (!element.parent && element.id > 0 && element.predefined) {
					item.layouts.push(element);
				} else {
					item.children.push(element);
				}
			}
		});
		item.layoutPages = [this.exportContent()];

		return item;
	},
	exportContent: function()
	{
		return {
			position: (this.getTarget().parent()
				.children(Layout.TAG).index(this.getTarget()))+1,
			layoutId: (this.id > 0 ? this.id : this.tmpId),
			startAt: this.startDate,
			endAt: this.endDate,
			html: this.template.cleanCode(
				this.getTarget().html()
			)
		};
	},
	json: function()
	{
		return JSON.stringify(
			this.export()
		);
	},
	refreshCss: function()
	{
		if (this.css) {
			this.getTarget().attr(
				'style', this.css
			);
		} else {
			this.getTarget()
				.removeAttr('style');
		}
	},
	getAllChildrenIds: function()
	{
		var ids = [];
		for(var i = 0; i < this.children.length; i++) {
			var result = this.children[i].getAllChildrenIds();
			ids = ids.concat(result);
		}

		ids.push(this.id);

		return ids;
	},
    getEditableZone: function()
    {
        return jQuery('.'+Layout.CONTENT_CLASS+', .'+Layout.ROW_CLASS, this.getTarget());
    },
    parseBool: function(value)
    {
    	return (
    		!(!value || value === 'false')
    	);
    }
});
Layout.TAG = 'cslayout';
Layout.NAME_CLASS = 'layout-name';
Layout.EDIT_CLASS = 'layout-edit';
Layout.RESIZE_CLASS = 'layout-resize';
Layout.TMP_ID = 'TMPID';
Layout.STYLES_CLASS = 'edit-styles';
Layout.BLOCKED_CLASS = 'layout-blocked';
Layout.CONTENT_CLASS = 'csl-inner';
Layout.ROW_CLASS = 'row';
