/*******************************************************************************
 * Copyright (c) 2004, 2016 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.ui.internal.intro.impl.swt;

import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Properties;

import org.eclipse.core.runtime.FileLocator;
import org.eclipse.core.runtime.Path;
import org.eclipse.jface.resource.JFaceResources;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.Image;
import org.eclipse.ui.forms.widgets.FormToolkit;
import org.eclipse.ui.internal.intro.impl.model.AbstractBaseIntroElement;
import org.eclipse.ui.internal.intro.impl.model.AbstractIntroContainer;
import org.eclipse.ui.internal.intro.impl.model.AbstractIntroElement;
import org.eclipse.ui.internal.intro.impl.model.AbstractIntroIdElement;
import org.eclipse.ui.internal.intro.impl.model.AbstractIntroPage;
import org.eclipse.ui.internal.intro.impl.model.IntroGroup;
import org.eclipse.ui.internal.intro.impl.model.IntroImage;
import org.eclipse.ui.internal.intro.impl.model.IntroLink;
import org.eclipse.ui.internal.intro.impl.model.IntroModelRoot;
import org.eclipse.ui.internal.intro.impl.model.IntroText;
import org.eclipse.ui.internal.intro.impl.model.loader.ModelLoaderUtil;
import org.eclipse.ui.internal.intro.impl.util.ImageUtil;
import org.eclipse.ui.internal.intro.impl.util.Log;
import org.osgi.framework.Bundle;

public class PageStyleManager extends SharedStyleManager {

    private AbstractIntroPage page;
	private Map<Properties, StyleContext> altStyleContexts = new HashMap<>();
    private IntroModelRoot root;


    /**
     * Constructor used when page styles need to be loaded. The plugin's bundle
     * is retrieved from the page model class. The default properties are
     * assumed to be the presentation shared properties. The inherrited
     * properties are properties that we got from included and extension styles.
     *
     * @param modelRoot
     */
    public PageStyleManager(AbstractIntroPage page, Properties sharedProperties) {
        this.page = page;
        context = new StyleContext();
        context.bundle = page.getBundle();

        // honor shared-style.
        if (page.injectSharedStyle())
            properties = new Properties(sharedProperties);
        else
            properties = new Properties();
        String altStyle = page.getAltStyle();
        if (altStyle != null) {
            load(properties, altStyle, context);
        }

        // AltStyles Hashtable has alt-styles as keys, the bundles as
        // values.
		Map<String, Bundle> altStyles = page.getAltStyles();
        if (altStyles != null) {
			for (Entry<String, Bundle> entry : altStyles.entrySet()) {
				String style = entry.getKey();
                Properties inheritedProperties = new Properties();
				Bundle bundle = entry.getValue();
                StyleContext sc = new StyleContext();
                sc.bundle = bundle;
                load(inheritedProperties, style, sc);
                altStyleContexts.put(inheritedProperties, sc);
            }
        }

        // cache root
        root = (IntroModelRoot) page.getParentPage().getParent();
    }


    // Override parent method to include alt-styles. Use implicit keys as well.
    @Override
	public String getProperty(String key) {
        return getProperty(key, true);
    }

    // Override parent method to include alt-styles. If useImplicit is true, we
    // try to resolve a key without its pageId.
    private String getProperty(String key, boolean useImplicitKey) {
        Properties aProperties = findPropertyOwner(key);
        String value = super.doGetProperty(aProperties, key);
        if (useImplicitKey) {
            if (value == null && page.getId() != null
                    && key.startsWith(page.getId())) {
                // did not find the key as-is. Trim pageId and try again.
                String relativeKey = key.substring(page.getId().length());
                return getProperty(relativeKey);
            }
        }
        return value;
    }


    /**
     * Finds a Properties that represents an inherited shared style, or this
     * current pages style. If the given key is not found, the pageId is trimmed
     * from the begining of the key, and the key is looked up again. If key does
     * not start with a pageId, lookup only the key as is.
     *
     * @param key
     * @return
     */
    private Properties findPropertyOwner(String key) {
        // search for the key in this page's properties first.
        if (properties.containsKey(key))
            return properties;

        // search inherited properties second.
		for (Properties aProperties : altStyleContexts.keySet()) {
            if (aProperties.containsKey(key))
                return aProperties;
        }
        // we did not find the key. Return the local properties anyway.
        return properties;
    }



    /**
     * Finds the context from which this key was loaded. If the key is not from
     * an inherited alt style, then use the context corresponding to this page.
     *
     * @param key
     * @return
     */

    @Override
	protected StyleContext getAssociatedContext(String key) {
        Properties aProperties = findPropertyOwner(key);
        StyleContext context = (StyleContext) altStyleContexts.get(aProperties);
        if (context != null)
            return context;
        return super.getAssociatedContext(key);
    }


    /*
     * For number of columns, do not return 1 as the default, to allow for
     * further processing. At the root page level, getting a 0 as ncolumns means
     * that the number of columns is the number of children. At the page level,
     * default is 1.
     */
    public int getPageNumberOfColumns() {
        return getIntProperty(page, ".layout.ncolumns", 0); //$NON-NLS-1$
    }


    public int getNumberOfColumns(IntroGroup group) {
        return getIntProperty(group, ".layout.ncolumns", 0); //$NON-NLS-1$
    }

    public boolean getEqualWidth(IntroGroup group) {
    	return getBooleanProperty(group, ".layout.equalWidth", false); //$NON-NLS-1$
    }

    public int getPageVerticalSpacing() {
        return getIntProperty(page, ".layout.vspacing", 5); //$NON-NLS-1$
    }

    public int getVerticalSpacing(IntroGroup group) {
        return getIntProperty(group, ".layout.vspacing", 5); //$NON-NLS-1$
    }

    public int getPageHorizantalSpacing() {
        return getIntProperty(page, ".layout.hspacing", 5); //$NON-NLS-1$
    }

    public int getHorizantalSpacing(IntroGroup group) {
        return getIntProperty(group, ".layout.hspacing", 5); //$NON-NLS-1$
    }

    public int getColSpan(AbstractBaseIntroElement element) {
        return getIntProperty(element, ".layout.colspan", 1); //$NON-NLS-1$
    }

    public int getRowSpan(AbstractBaseIntroElement element) {
        return getIntProperty(element, ".layout.rowspan", 1); //$NON-NLS-1$
    }

    private int getIntProperty(AbstractBaseIntroElement element,
            String qualifier, int defaultValue) {
        StringBuffer buff = ModelLoaderUtil.createPathToElementKey(element, true);
        if (buff == null)
            return defaultValue;
        String key = buff.append(qualifier).toString();
        return getIntProperty(key, defaultValue);
    }

    private boolean getBooleanProperty(AbstractBaseIntroElement element,
            String qualifier, boolean defaultValue) {
        StringBuffer buff = ModelLoaderUtil.createPathToElementKey(element, true);
        if (buff == null)
            return defaultValue;
        String key = buff.append(qualifier).toString();
        return getBooleanProperty(key, defaultValue);
    }

    private int getIntProperty(String key, int defaulValue) {
        int intValue = defaulValue;
        String value = getProperty(key);
        if (value == null)
            return intValue;

        try {
            intValue = Integer.parseInt(value);
        } catch (NumberFormatException e) {
            Log.error("Failed to parse key: " + key + " as an integer.", e); //$NON-NLS-1$ //$NON-NLS-2$
        }
        return intValue;
    }

    private boolean getBooleanProperty(String key, boolean defaultValue) {
        boolean booleanValue = defaultValue;
        String value = getProperty(key);
        if (value != null)
        	booleanValue = value.equalsIgnoreCase("true"); //$NON-NLS-1$
        return booleanValue;
    }


    /**
     * Finds the description text of the given group. Looks for the Text child
     * element whos id is specified as follows:
     * <p>
     * <pageId>. <path_to_group>.description-id= <id of child description Text
     * element>
     * </p>
     * If not found, use the default description style.
     *
     * Returns null if no default style found, or any id in path is null.
     *
     * @param group
     * @return
     */
    public String getDescription(IntroGroup group) {
        StringBuffer buff = ModelLoaderUtil.createPathToElementKey(group, true);
        if (buff == null)
            return null;
        String key = buff.append(".description-id").toString(); //$NON-NLS-1$
        return doGetDescription(group, key);
    }


    /**
     * Finds the description text of the associated page. Looks for the Text
     * child element whos id is specified as follows:
     * <p>
     * <pageId>.description-id= <id of child description Text element>
     * </p>
     * If not found, use the default description style.
     *
     * Returns null if no default style found, or any id in path is null.
     *
     * @param group
     * @return
     */
    public String getPageDescription() {
        if (page.getId() == null)
            return null;
        String key = page.getId() + ".description-id"; //$NON-NLS-1$
        return doGetDescription(page, key);
    }

    private String doGetDescription(AbstractIntroContainer parent, String key) {
        String path = getProperty(key);
        String description = null;
        if (path != null)
            description = findTextFromPath(parent, path);
        if (description != null)
            return description;
        return findTextFromStyleId(parent, getDescriptionStyleId());
    }

    private String getDescriptionStyleId() {
        String key = "description-style-id"; //$NON-NLS-1$
        return getProperty(key);
    }

    /**
     * Finds the subtitle of the associated page. Looks for the Text child
     * element whose id is specified as follows:
     * <p>
     * <pageId>.description-id= <id of child description Text element>
     * </p>
     * If not found, use the default description style.
     *
     * @param group
     * @return
     */
    public String getPageSubTitle() {
        String key = page.getId() + ".subtitle-id"; //$NON-NLS-1$
        String path = getProperty(key);
        String description = null;
        if (path != null)
            description = findTextFromPath(page, path);
        if (description != null)
            return description;
        return findTextFromStyleId(page, getPageSubTitleStyleId());
    }

    private String getPageSubTitleStyleId() {
        String key = "subtitle-style-id"; //$NON-NLS-1$
        return getProperty(key);
    }

    private String findTextFromPath(AbstractIntroContainer parent, String path) {
        AbstractIntroElement child = parent.findTarget(root, path);
        if (child != null && child.isOfType(AbstractIntroElement.TEXT)) {
            makeFiltered(child);
            return ((IntroText) child).getText();
        }
        return null;
    }

    /**
     * Returns the first direct child text element with the given style-id.
     *
     * @return
     */
    private String findTextFromStyleId(AbstractIntroContainer parent,
            String styleId) {
        IntroText[] allText = (IntroText[]) parent
            .getChildrenOfType(AbstractIntroElement.TEXT);
        for (int i = 0; i < allText.length; i++) {
            if (allText[i].getStyleId() == null)
                // not all elements have style id.
                continue;
            if (allText[i].getStyleId().equals(styleId)) {
                makeFiltered(allText[i]);
                return allText[i].getText();
            }
        }
        return null;
    }

    /**
     * Util method to check model type, and filter model element out if it is of
     * the correct type.
     *
     * @param element
     */
    private AbstractIntroElement makeFiltered(AbstractIntroElement element) {
        if (element.isOfType(AbstractIntroElement.BASE_ELEMENT))
            ((AbstractBaseIntroElement) element).setFilterState(true);
        return element;
    }



    public boolean getShowLinkDescription() {
        String key = page.getId() + ".show-link-description"; //$NON-NLS-1$
        String value = getProperty(key);
        if (value == null) {
            key = ".show-link-description"; //$NON-NLS-1$
            value = getProperty(key);
        }
        if (value == null)
            value = "true"; //$NON-NLS-1$
        return value.toLowerCase().equals("true"); //$NON-NLS-1$
    }

    public boolean showHomePageNavigation() {
        String key = page.getId() + ".show-home-page-navigation"; //$NON-NLS-1$
        String value = getProperty(key);
        if (value == null) {
            key = ".show-home-page-navigation"; //$NON-NLS-1$
            value = getProperty(key);
        }
        if (value == null)
            value = "true"; //$NON-NLS-1$
        return value.equalsIgnoreCase("true"); //$NON-NLS-1$
    }


    public Color getColor(FormToolkit toolkit, AbstractBaseIntroElement element) {
        StringBuffer buff = ModelLoaderUtil.createPathToElementKey(element, true);
        if (buff == null)
            return null;
        String key = buff.append(".font.fg").toString(); //$NON-NLS-1$
        return getColor(toolkit, key);
    }

    public Color getBackgrond(FormToolkit toolkit, AbstractBaseIntroElement element) {
        StringBuffer buff = ModelLoaderUtil.createPathToElementKey(element, true);
        if (buff == null)
            return null;
        String key = buff.append(".bg").toString(); //$NON-NLS-1$
        return getColor(toolkit, key);
    }

    public boolean isBold(IntroText text) {
        String value = null;
        /*
        StringBuffer buff = ModelLoaderUtil.createPathToElementKey(text, true);
        if (buff != null) {
            String key = buff.append(".font.bold").toString(); //$NON-NLS-1$
            value = getProperty(key);
            if (value != null)
                return value.toLowerCase().equals("true"); //$NON-NLS-1$
            else {
                buff = ModelLoaderUtil.createPathToElementKey(text, true);
            }
        }
        */
        value = getPropertyValue(text, ".font.bold"); //$NON-NLS-1$
        if (value == null) {
            // bold is not specified by ID. Check to see if there is a style-id
            // specified for bold.
            value = getProperty("bold-style-id"); //$NON-NLS-1$
            if (value != null && text.getStyleId() != null)
                return text.getStyleId().equals(value);
        }
        return false;
    }

    private String getPropertyValue(AbstractIntroIdElement element, String suffix) {
        StringBuffer buff = ModelLoaderUtil.createPathToElementKey(element, true);
        if (buff != null) {
        	String key = buff.append(suffix).toString();
        	String value = getProperty(key);
        	if (value != null)
        		return value;
        	// try the page.id key
        	buff = ModelLoaderUtil.createPathToElementKey(element, false);
        	if (buff!= null) {
        		key = buff.append(suffix).toString();
        		value = getProperty(key);
        		return value;
        	}
        }
        return null;
    }

    public static Font getBannerFont() {
        return JFaceResources.getBannerFont();
    }

    public static Font getHeaderFont() {
        return JFaceResources.getHeaderFont();
    }

    /**
     * Retrieves an image for a link in a page. If not found, uses the page's
     * default link image. If still not found, uses the passed default.
     *
     * @param link
     * @param qualifier
     * @return
     */
    public Image getImage(IntroLink link, String qualifier, String defaultKey) {
    	// try the Id first
    	String key = createImageByIdKey(page, link, qualifier);
    	String value = getProperty(key, false);
    	if (value==null) {
    		key = createImageKey(page, link, qualifier);
    		// special case where we have to handle this because extended code does
    		// not go through getProperty() in this method.
    		value = getProperty(key, false);
    	}
        if (value == null && page.getId() != null
                && key.startsWith(page.getId()))
            // did not use the key as-is. Trim pageId and try again.
            key = key.substring(page.getId().length());

        // pageKey can not become an implicit key.
        String pageKey = createImageKey(page, null, qualifier);

        return getImage(key, pageKey, defaultKey);
    }

    private String createImageKey(AbstractIntroPage page, IntroLink link,
            String qualifier) {
        StringBuffer buff = null;
        if (link != null) {
            buff = ModelLoaderUtil.createPathToElementKey(link, true);
            if (buff == null)
                return ""; //$NON-NLS-1$
        } else {
            buff = new StringBuffer();
            buff.append(page.getId());
        }
        buff.append("."); //$NON-NLS-1$
        buff.append(qualifier);
        return buff.toString();
    }

    private String createImageByIdKey(AbstractIntroPage page, IntroLink link,
            String qualifier) {
    	if (link==null || link.getId()==null)
    		return ""; //$NON-NLS-1$
        StringBuffer buff = new StringBuffer();
        buff.append(page.getId());
        buff.append("."); //$NON-NLS-1$
        buff.append(link.getId());
        buff.append("."); //$NON-NLS-1$
        buff.append(qualifier);
        return buff.toString();
    }

    public Image getImage(IntroImage introImage) {
        String imageLocation = introImage.getSrcAsIs();
        StringBuffer buff = ModelLoaderUtil.createPathToElementKey(introImage, true);
        String key;
        if (buff == null) {
        	key = "//" + imageLocation; //$NON-NLS-1$
        } else {
        	key = buff!=null?buff.toString():null;
        }
        if (ImageUtil.hasImage(key))
            return ImageUtil.getImage(key);
        // key not already registered.
        if (buff != null) {
        	StyleContext acontext = getAssociatedContext(key);
            if (acontext.inTheme) {
               	ImageUtil.registerImage(key, acontext.path, imageLocation);
                return ImageUtil.getImage(key);
            }
        }
        Bundle bundle = introImage.getBundle();
		if (FileLocator.find(bundle, new Path(imageLocation), null) == null) {
			return null;
		}
        ImageUtil.registerImage(key, bundle, imageLocation);
        return ImageUtil.getImage(key);

    }


}
