/**
 *                                                                            
 *  Copyright (c) 2011, 2016 - 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                                 
 *                                                                            
 *  Contributors:                                                      
 * 	   Christophe Loetz (Loetz GmbH&Co.KG) - initial implementation
 * 
 */
package org.eclipse.osbp.vaaclipse.addons.softwarefactory.service;

import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.Hashtable;
import java.util.List;
import java.util.Locale;

import org.eclipse.equinox.app.IApplicationContext;
import org.eclipse.osbp.ui.api.themes.IThemeResourceService;
import org.eclipse.osbp.vaaclipse.publicapi.theme.ThemeEngine;
import org.eclipse.osbp.vaaclipse.publicapi.theme.ThemeManager;
import org.osgi.service.component.annotations.Component;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.vaadin.server.Resource;
import com.vaadin.server.ThemeResource;

@Component(immediate = true)
public class ThemeResourceService implements IThemeResourceService {

	protected static final class TypeItem {

		protected final String path;
		protected final String extension;

		protected TypeItem(String path, String extension) {
			this.path = path;
			this.extension = extension;
		}

	}

	private static final Hashtable<ThemeResourceType, TypeItem> ThemeTypetoLocatorMap = new Hashtable<ThemeResourceType, TypeItem>() {
		private static final long serialVersionUID = -3532016435445400246L;
		{
			put(ThemeResourceType.IMAGE, new TypeItem(ThemeResourceType.IMAGE.toString().toLowerCase() + "/", ".jpg"));
			put(ThemeResourceType.ICON, new TypeItem(ThemeResourceType.ICON.toString().toLowerCase() + "/", ".png"));
			put(ThemeResourceType.FLAG, new TypeItem(ThemeResourceType.FLAG.toString().toLowerCase() + "/", ".gif"));
			put(ThemeResourceType.HTML, new TypeItem(ThemeResourceType.HTML.toString().toLowerCase() + "/", ".html"));
			put(ThemeResourceType.SOUND, new TypeItem(ThemeResourceType.SOUND.toString().toLowerCase() + "/", ".mp3"));
			put(ThemeResourceType.VIDEO, new TypeItem(ThemeResourceType.VIDEO.toString().toLowerCase() + "/", ".mp4"));
		}
	};

	private ThemeEngine themeEngine;
	private ThemeManager themeManager;

	private List<String> cssUris = null;
	private String resourcePath = null;


	private static final Logger LOGGER = LoggerFactory.getLogger(ThemeResourceService.class);
	
	@Override
	public void init(IApplicationContext appContext, Object themeEngine, Object themeManager) {
		this.themeEngine = (ThemeEngine)themeEngine;
		this.themeManager = (ThemeManager)themeManager;
		reset();
	}

	public void reset() {
		cssUris = themeEngine.getTheme(themeManager.getThemeId()).getAllResourceLocationURIs();
		if (cssUris != null && !cssUris.isEmpty()) {
			resourcePath = cssUris.get(0);
		}
	}

	@Override
	public String getThemeURI(String resourceID, ThemeResourceType themeResourceType) {
		if (resourceID != null) {
			return resourcePath + getRelativeResourePath(resourceID, themeResourceType);
		} else {
			return null;
		}
	}
	
	@Override
	public Resource getThemeResource(String resourceID, ThemeResourceType themeResourceType) {
		if (resourceID != null) {
			return new ThemeResource(getRelativeResourePath(resourceID, themeResourceType));
		} else {
			return null;
		}
	}

	protected String getRelativeResourePath(String resourceID, ThemeResourceType themeResourceType) {
		if (resourceID != null) {
			return getThemeResourceTypePath(themeResourceType) + resourceID + getThemeResourceTypeExtension(themeResourceType);
		} else {
			return null;
		}
	}

	@Override
	public String getThemeResourceTypeExtension(ThemeResourceType themeResourceType) {
		return ThemeTypetoLocatorMap.get(themeResourceType).extension;
	}

	@Override
	public String getThemeResourceTypePath(ThemeResourceType themeResourceType) {
		return ThemeTypetoLocatorMap.get(themeResourceType).path;
	}

	@Override
	public InputStream getThemeResourceInputStream(String resourceURL) {
		InputStream stream = null;
		try {
			// this works with platform:// url format
			URL url = new URL(resourceURL);
		    stream = url.openConnection().getInputStream();
		}
		catch (IOException e) {
			LOGGER.warn("resource url '"+resourceURL+"' could not be loaded", e);
		}		
		return stream;
	}

	@Override
	public InputStream getThemeResourceInputStream(String resourceID, ThemeResourceType themeResourceType) {
		return getThemeResourceInputStream(getThemeURI(resourceID, themeResourceType));
	}
	
	@Override
	public String getThemeResourceHTML(String subject, Locale locale) {
		String localeTag = locale.toLanguageTag();
		String path = getRelativeResourePath(subject, ThemeResourceType.HTML);
		String theme = themeManager.getThemeId();
		StringBuilder htmlLoader = new StringBuilder();
		htmlLoader.append("<iframe src=\"./VAADIN/themes/$THEME$/$PATH$?localeTag=$LOCALETAG$\""); 
		htmlLoader.append("\twidth=\"100%\" height=\"100%\" name=\"$SUBJECT$ page\">");
		htmlLoader.append("\t\t<p>Alternative $SUBJECT$ page</p>");
		htmlLoader.append("</iframe>");
		return htmlLoader.toString().replace("$SUBJEC$T", subject).replace("$THEME$", theme).replace("$PATH$", path).replace("$LOCALETAG$", localeTag);
	}

	@Override
	public String getThemeResourceRelativePath(String resourceID, ThemeResourceType themeResourceType) {
		if (resourceID != null) {
			String relativePath = "./"+resourcePath.substring(resourcePath.indexOf("VAADIN"));
			return relativePath + getRelativeResourePath(resourceID, themeResourceType);
		} else {
			return null;
		}
	}

	@Override
	public String getThemeResourceMxGraphPath() {
		String theme = themeManager.getThemeId();
		return "./VAADIN/themes/" + theme + "/mxGraph";
	}
	
}
