package org.mt4j.components.css.util;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import org.mt4j.AbstractMTApplication;
import org.mt4j.components.MTComponent;
import org.mt4j.components.css.parser.CSSHandler;
import org.mt4j.components.css.parser.CSSParserConnection;
import org.mt4j.components.css.style.CSSSelector;
import org.mt4j.components.css.style.CSSStyle;
import org.mt4j.components.css.style.CSSStyleHierarchy;
import org.mt4j.util.MTColor;
import org.mt4j.util.font.FontManager;
import org.mt4j.util.font.IFont;
/**
* The Class CSSStyleManager.
*/
public class CSSStyleManager {
/** The components (of registered MTComponents). */
private List<CSSStylableComponent> components = new ArrayList<CSSStylableComponent>();
/** The MTApplication. */
private AbstractMTApplication app = null;
/** The styles. */
private List<CSSStyleHierarchy> styles = new ArrayList<CSSStyleHierarchy>();
/** CSS Styles globally enabled. */
private boolean globallyEnabled = false;
/** CSS Styles globally disabled. */
private boolean globallyDisabled = false;
/** The default font. */
private IFont defaultFont = null;
/**
* Instantiates a new (empty) CSS style manager.
*
* @param app the MTApplication
*/
public CSSStyleManager(AbstractMTApplication app) {
this.app = app;
}
/**
* Instantiates a new CSS style manager.
*
* @param styles the CSSStyles
* @param app the MTApplication
*/
public CSSStyleManager(List<CSSStyle> styles, AbstractMTApplication app) {
for (CSSStyle s: styles) {
this.styles.add(new CSSStyleHierarchy(s));
}
this.app = app;
}
/**
* Register component.
*
* @param c the c
*/
public void registerComponent(CSSStylableComponent c) {
components.add(c);
}
/**
* Load styles from file.
*
* @param uri the uri of the file
*/
public void loadStyles(String uri) {
CSSParserConnection pc = new CSSParserConnection(uri, app);
CSSHandler handler = pc.getCssh();
if (handler != null) {
List<CSSStyle> newStyles = handler.getStyles();
for (CSSStyle s: newStyles) {
this.styles.add(new CSSStyleHierarchy(s));
}
}
}
/**
* Load styles from InputStream.
*
* @param input the input
*/
public void loadStyles(InputStream input) {
CSSParserConnection pc = new CSSParserConnection(input, app);
CSSHandler handler = pc.getCssh();
if (handler != null) {
List<CSSStyle> newStyles = handler.getStyles();
for (CSSStyle s: newStyles) {
this.styles.add(new CSSStyleHierarchy(s));
}
}
}
/**
* Load styles from src folder.
* css source file has to be located in /src/data/css/ folder
*
* @param uri the uri
*/
public void loadStylesFromSrcFolder(String uri) {
this.loadStyles(Thread.currentThread().getContextClassLoader().getResourceAsStream("data/css/" + uri));
}
/**
* Load styles and override selectors.
*
* @param uri the uri
* @param selector the selector
*/
public void loadStylesAndOverrideSelector(String uri, CSSSelector selector) {
CSSParserConnection pc = new CSSParserConnection(uri, app);
CSSHandler handler = pc.getCssh();
if (handler != null) {
List<CSSStyle> newStyles = handler.getStyles();
for (CSSStyle s: newStyles) {
s.setSelector(selector);
this.styles.add(new CSSStyleHierarchy(s));
}
}
}
/**
* Clear all styles.
*/
public void clearStyles() {
this.styles.clear();
applyStyles();
}
/**
* Checks if is globally enabled.
*
* @return true, if CSS Styles is globally enabled
*/
public boolean isGloballyEnabled() {
return globallyEnabled;
}
/**
* Sets the CSS Styles globally enabled.
*
* @param globallyEnabled the new globally enabled
*/
public void setGloballyEnabled(boolean globallyEnabled) {
this.globallyEnabled = globallyEnabled;
if (globallyEnabled) this.globallyDisabled = false;
applyStyles();
}
/**
* Checks if CSS Styles is globally disabled.
*
* @return true, if is globally disabled
*/
public boolean isGloballyDisabled() {
return globallyDisabled;
}
/**
* Sets the CSS Styles globally disabled.
*
* @param globallyDisabled the new globally disabled
*/
public void setGloballyDisabled(boolean globallyDisabled) {
this.globallyDisabled = globallyDisabled;
if (globallyDisabled) this.globallyEnabled = false;
applyStyles();
}
/**
* Gets the styles.
*
* @return the styles
*/
public List<CSSStyleHierarchy> getStyles() {
return styles;
}
/**
* Sets the styles.
*
* @param styles the new styles
*/
public void setStyles(List<CSSStyleHierarchy> styles) {
this.styles = styles;
applyStyles();
}
/**
* Adds a style.
*
* @param style the style
*/
public void addStyle(CSSStyle style) {
this.styles.add(new CSSStyleHierarchy(style));
applyStyles();
}
/**
* Adds a style with a certain priority.
*
* @param style the style
* @param priority the priority
*/
public void addStyle(CSSStyle style, int priority) {
this.styles.add(new CSSStyleHierarchy(style, priority));
applyStyles();
}
/**
* Removes a style.
*
* @param style the style
*/
public void removeStyle(CSSStyle style) {
this.styles.remove(style);
applyStyles();
}
/**
* Applies the global style sheets on all registered components.
*/
public void applyStyles() {
List<CSSStylableComponent> toDelete = new ArrayList<CSSStylableComponent>();
for (CSSStylableComponent c: components) {
if (c != null) {
if (!this.isGloballyDisabled()) c.applyStyleSheet();
} else {
toDelete.add(c);
}
}
components.removeAll(toDelete);
}
/**
* Gets the first style which contains a specific selector.
*
* @param s the Selector
* @return the first style which contains the selector
*/
public CSSStyle getFirstStyleForSelector(CSSSelector s) {
for (CSSStyleHierarchy sty: styles) {
if (sty.getStyle().getSelector().equals(s)){
return sty.getStyle();
}
}
return null;
}
/**
* Gets all relevant styles for a MTComponent.
*
* @param c the MTComponent
* @return the relevant styles
*/
public List<CSSStyleHierarchy> getRelevantStyles(MTComponent c) {
if (!components.contains(c) && c instanceof CSSStylableComponent){
components.add((CSSStylableComponent)c);
}
List<CSSStyleHierarchy> relevantStyles = new ArrayList<CSSStyleHierarchy>();
for (CSSStyleHierarchy s: styles) {
int temp = s.getStyle().getSelector().appliesTo(c);
if (temp != 0)
//Debug Only
//Logger.getLogger("MT4J Extensions").debug("Relevant Style? " + temp + " (" + s.getStyle().getSelector() + ")");
if (temp != 0) {
relevantStyles.add(new CSSStyleHierarchy(s, temp % 100, (short)(temp / 100)));
}
}
return relevantStyles;
}
/**
* Gets the default font.
*
* @param app the app
* @return the default font
*/
public IFont getDefaultFont(AbstractMTApplication app) {
if (defaultFont == null) {
defaultFont = FontManager.getInstance().createFont(app,
"SansSerif", 16, // Font size
MTColor.WHITE);
}
return defaultFont;
}
}