/*
 *                                                                            
 *  Copyright (c) 2011 - 2017 - Loetz GmbH & Co KG, 69115 Heidelberg, Germany 
 *                                                                            
 *  All rights reserved. This program and the accompanying materials           
 *  are made available under the terms of the Eclipse Public License 2.0        
 *  which accompanies this distribution, and is available at                  
 *  https://www.eclipse.org/legal/epl-2.0/                                 
 *                                 
 *  SPDX-License-Identifier: EPL-2.0                                 
 *                                                                            
 *  Initial contribution:                                                      
 *     Loetz GmbH & Co. KG
 * 
 */
package org.eclipse.osbp.utils.vaadin;

import org.eclipse.e4.core.contexts.IEclipseContext;
import org.eclipse.osbp.ui.api.layout.IViewLayoutManager;
import org.eclipse.osbp.ui.api.themes.EnumCssClass;
import org.eclipse.osbp.ui.api.themes.IThemeResourceService;
import org.eclipse.osbp.ui.api.themes.IThemeResourceService.ThemeResourceType;

import com.vaadin.server.Extension;
import com.vaadin.server.Page;
import com.vaadin.ui.AbstractOrderedLayout;
import com.vaadin.ui.HorizontalLayout;
import com.vaadin.ui.Label;
import com.vaadin.ui.VerticalLayout;

/**
 * The Class ViewLayoutManager.
 */
public class ViewLayoutManager implements IViewLayoutManager {
	private Label label;
	private ExtendedVerticalLayout workArea;
	private HorizontalLayout topArea;
	private VerticalLayout sideArea;
	private VerticalLayout dataArea;
	private String caption;

	@Override
	public void init(AbstractOrderedLayout parent) {
		init(parent, null, null);
	}
	
	@Override
	public void init(AbstractOrderedLayout parent, String styleName, String imagePath) {
		label = new Label();
		label.addStyleName(EnumCssClass.VIEW_HEADER_H2.toString());
		label.setSizeUndefined();

		topArea = new HorizontalLayout(label);
		topArea.addStyleName(EnumCssClass.TOP_AREA.toString());
		topArea.setSizeUndefined();
		
		sideArea = new VerticalLayout();
		sideArea.addStyleName(EnumCssClass.SIDE_AREA.toString());
	    sideArea.setSizeUndefined();

	    dataArea = new VerticalLayout();
	    dataArea.addStyleName(EnumCssClass.DATA_AREA.toString());
	    dataArea.setSizeFull();
	    if(imagePath != null) {
		    dataArea.addStyleName(styleName);
	    	addStyle(styleName, imagePath);
	    }
	    
	    HorizontalLayout multiArea = new HorizontalLayout(sideArea, dataArea);
	    multiArea.addStyleName(EnumCssClass.MULTI_AREA.toString());
	    multiArea.setSizeFull();
	    multiArea.setExpandRatio(dataArea, 1);

	    workArea = new ExtendedVerticalLayout();
		workArea.addStyleName(EnumCssClass.WORK_AREA.toString());
	    workArea.setSizeFull();
	    workArea.addComponent(topArea);
	    workArea.addComponent(multiArea);
	    workArea.setExpandRatio(multiArea, 1);
	    if(parent != null) {
		    parent.setPrimaryStyleName("osbp");
		    parent.addStyleName(EnumCssClass.VIEW.toString());
		    parent.addComponent(workArea);
		    parent.setExpandRatio(workArea, 1);
	    }
	}

	private void addStyle(String styleName, String imagePath) {
    	String style = "."+styleName+" { background: url(\""+
    	imagePath+
    	"\") no-repeat ;" +			// center center fixed
    	"-webkit-background-size: cover;" +
    	"-moz-background-size: cover;" +
    	"-o-background-size: cover;" +
    	"background-size: cover; }";
    	Page.getCurrent().getStyles().add(style);
	}

	@Override
	public void addExtension(Extension extension) {
		workArea.addExtension(extension);
	}

	@Override
	public void removeExtension(Extension extension) {
		workArea.removeExtension(extension);
	}

	@Override
	public void setLabelValue(String text) {
		this.caption = text;
		if(text == null || text.isEmpty()) {
			label.setWidth("0px");
			label.setHeight("0px");
		} else {
			label.setValue(text);
		}
	}

	@Override
	public HorizontalLayout getTopArea() {
		return topArea;
	}

	@Override
	public VerticalLayout getSideArea() {
		return sideArea;
	}

	@Override
	public VerticalLayout getDataArea() {
		return dataArea;
	}

	@Override
	public String getCaption() {
		return caption;
	}
}
