/**
 * Copyright (c) 2011 Forschungszentrum Juelich GmbH
 * 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:
 * 		Carsten Karbach, Claudia Knobloch, FZ Juelich
 */

package org.eclipse.ptp.rm.lml.internal.core.model;

import java.io.OutputStream;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBElement;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.namespace.QName;

import org.eclipse.ptp.rm.lml.core.events.ILguiUpdatedEvent;
import org.eclipse.ptp.rm.lml.core.listeners.ILguiListener;
import org.eclipse.ptp.rm.lml.core.model.ILguiItem;
import org.eclipse.ptp.rm.lml.internal.core.elements.AbslayoutType;
import org.eclipse.ptp.rm.lml.internal.core.elements.ChartType;
import org.eclipse.ptp.rm.lml.internal.core.elements.ChartgroupType;
import org.eclipse.ptp.rm.lml.internal.core.elements.ChartlayoutType;
import org.eclipse.ptp.rm.lml.internal.core.elements.ColumnlayoutType;
import org.eclipse.ptp.rm.lml.internal.core.elements.ComponentType;
import org.eclipse.ptp.rm.lml.internal.core.elements.ComponentlayoutType;
import org.eclipse.ptp.rm.lml.internal.core.elements.DataType;
import org.eclipse.ptp.rm.lml.internal.core.elements.GobjectType;
import org.eclipse.ptp.rm.lml.internal.core.elements.InfoboxType;
import org.eclipse.ptp.rm.lml.internal.core.elements.InfoboxlayoutType;
import org.eclipse.ptp.rm.lml.internal.core.elements.LayoutType;
import org.eclipse.ptp.rm.lml.internal.core.elements.LguiType;
import org.eclipse.ptp.rm.lml.internal.core.elements.Nodedisplay;
import org.eclipse.ptp.rm.lml.internal.core.elements.NodedisplaylayoutType;
import org.eclipse.ptp.rm.lml.internal.core.elements.ObjectFactory;
import org.eclipse.ptp.rm.lml.internal.core.elements.PaneType;
import org.eclipse.ptp.rm.lml.internal.core.elements.SchemeType;
import org.eclipse.ptp.rm.lml.internal.core.elements.SplitlayoutType;
import org.eclipse.ptp.rm.lml.internal.core.elements.TableType;
import org.eclipse.ptp.rm.lml.internal.core.elements.TablelayoutType;
import org.eclipse.ptp.rm.lml.internal.core.elements.TextboxType;
import org.eclipse.ptp.rm.lml.internal.core.elements.UsagebarType;
import org.eclipse.ptp.rm.lml.internal.core.elements.UsagebarlayoutType;

/**
 * This class provides access to component-layout-definitions.
 * Returns layout-objects for standard-lml-objects
 * 
 * Moreover with this class one is able to manipulate layout definitions
 * LML-Models can be transformed into layout-only definitions
 * There are functions, which allow to merge layouts to one lml-model
 *  
 *  
 * @author karbach
 *
 */
public class LayoutAccess extends LguiHandler{	
	//DefaultLayouts
	private UsagebarlayoutType defaultUsagebar;
	private ChartlayoutType defaultChart;
	private TablelayoutType defaultTable;
	private InfoboxlayoutType defaultInfobox;
	
	private static ObjectFactory objectFactory = new ObjectFactory();//create a objectfactory for all functions in this class
	
	/**
	 * @param lguiItem LML-data-handler, which groups this handler and others to a set
	 * of LMLHandler. This instance is needed to notify all LMLHandler, if any data of
	 * the LguiType-instance was changed.
	 */
	public LayoutAccess(ILguiItem lguiItem, LguiType lgui){
		super(lguiItem, lgui);
		defaultUsagebar = objectFactory.createUsagebarlayoutType();
		defaultChart = objectFactory.createChartlayoutType();
		defaultTable = objectFactory.createTablelayoutType();
		defaultInfobox = objectFactory.createInfoboxlayoutType();
		
		this.lguiItem.addListener(new ILguiListener() {
			public void handleEvent(ILguiUpdatedEvent e) {
				update(e.getLguiItem().getLguiType());
			}
		});
	}
	
	/**
	 * Replace all componentlayouts for a graphical object with given gid through newlayout.getGid()
	 * with newlayout
	 * @param newLayout new layout, which is placed into the positions of old layouts
	 */
	public void replaceComponentLayout(ComponentlayoutType newlayout){
		if(newlayout==null) return;
		String gid=newlayout.getGid();
		
		List<JAXBElement<?>> allobjects=lgui.getObjectsAndRelationsAndInformation();
		
		boolean replaced=false;
		
		//Over all objects in lml-file
		for(JAXBElement<?> aobj: allobjects){
			//Over all Componentlayouts
			if(aobj.getValue() instanceof ComponentlayoutType){
				
				ComponentlayoutType alayout=(ComponentlayoutType)aobj.getValue();
				
				if( alayout.getGid()!=null && alayout.getGid().equals(gid) ){
					((JAXBElement<ComponentlayoutType>)aobj).setValue(newlayout);
					replaced=true;
				}
				
			}
		}
		
		if(!replaced){//Insert new layout, if there was nothing to replace
			//Takes any componentlayout
			JAXBElement<?> newel=null;
			
			//Differ between several layouts, create different JAXBElements
			if(newlayout instanceof TablelayoutType){
				newel=new JAXBElement<TablelayoutType>( new QName("tablelayout"), 
											   TablelayoutType.class, (TablelayoutType)newlayout );
			}
			else if(newlayout instanceof NodedisplaylayoutType){
				newel=new JAXBElement<NodedisplaylayoutType>( new QName("nodedisplaylayout"), 
						   NodedisplaylayoutType.class, (NodedisplaylayoutType)newlayout );
			}
			
			if(newel!=null)
				lgui.getObjectsAndRelationsAndInformation().add(newel);
		}
		
	}
	
	/**
	 * Simply returns the first layout found for a usagebar with the given id
	 * or a default-layout
	 * @param usagebarID
	 * @return defaultlayout for a usagebar or first layout for usagebar with id usagebarid given by lml-file
	 */
	public UsagebarlayoutType getUsagebarLayout(String usagebarID) {
		List<UsagebarlayoutType> usagebarLayouts = getUsagebarLayouts();
		//Over all objects in lml-file
		for (UsagebarlayoutType usagebarLayout : usagebarLayouts) {
			if (usagebarLayout.getGid().equals(usagebarID))
				return usagebarLayout;
		}
		return defaultUsagebar;		
	}
	

	/**
	 * Simply returns the first layout found for a chart with the given id
	 * or a default-layout
	 * @param chartID
	 * @return defaultlayout for a chart or first layout for chart with id chartid given by lml-file
	 */
	public ChartlayoutType getChartLayout(String chartID) {
		List<ChartlayoutType> chartLayouts = getChartLayouts();
		for (ChartlayoutType chartLayout : chartLayouts){
			if (chartLayout.getGid().equals(chartID))
				return chartLayout;
		}
		return defaultChart;		
	}
	
	
	/**
	 * Simply returns the first layout found for a infobox with the given id
	 * or a default-layout
	 * @param infoID
	 * @return defaultlayout for a table or first layout for table with id tableid given by lml-file
	 */
	public InfoboxlayoutType getInfoboxLayout(String infoID){
		List<InfoboxlayoutType> infoboxLayouts = getInfoboxLayout();
		for (InfoboxlayoutType infoboxLayout : infoboxLayouts) {
			if (infoboxLayout.getGid().equals(infoID) )
				return infoboxLayout;
		}
		return defaultInfobox;		
	}
	
	private List<InfoboxlayoutType> getInfoboxLayout() {
		List<InfoboxlayoutType> infoboxLayouts = new LinkedList<InfoboxlayoutType>();
		for (ComponentlayoutType tag : getComponentLayouts()) {
			if (tag instanceof InfoboxlayoutType) {
				infoboxLayouts.add((InfoboxlayoutType) tag);
			}
		}
		return infoboxLayouts;
	}

	/**
	 * This function is only for easier understanding this class
	 * Textboxlayouts are identical to infoboxlayouts, so you could
	 * call getInfoboxLayout(textid) and would get the same result.
	 * 
	 * @param textID id of a textbox
	 * @return layout for a textbox with an info-tag in it
	 */
	public InfoboxlayoutType getTextboxLayout(String textID){
		return getInfoboxLayout(textID);
	}
	
	/**
	 * @param data model of lml-data, contingently with layout-information, this object will be modified and returned 
	 * @param layout more important layout-data, overwrite componentlayouts of data-model, but add additional abs/-splitlayouts
	 * @return merged lml-model
	 */
	public static LguiType mergeLayouts(LguiType data, LguiType layout){
		
		if(data==null || layout==null) return data;
		LguiItem lgui = new LguiItem(data);
		LayoutAccess la=new LayoutAccess(lgui, lgui.getLguiType());
		//Replace component-layouts
		for(JAXBElement<?> el:layout.getObjectsAndRelationsAndInformation()){
			if(el.getValue() instanceof ComponentlayoutType){
				la.replaceComponentLayout((ComponentlayoutType)el.getValue());
			}
		}
		
		/** really merge layouts, do not overwrite
		//Collect existing layout-ids
		HashSet<String> layoutids=new HashSet<String>();
		
		for(JAXBElement<?> el:data.getObjectsAndRelationsAndInformation()){
			if(el.getValue() instanceof LayoutType){
				LayoutType lay=(LayoutType) el.getValue();
				layoutids.add(lay.getId());
			}
		}
		
		//Generate new ids if layout-ids already exist in data, then add new layout to data
		for(JAXBElement<?> el:layout.getObjectsAndRelationsAndInformation()){
			if(el.getValue() instanceof LayoutType){
				LayoutType lay=(LayoutType) el.getValue();
				
				String newid=lay.getId();
				while(layoutids.contains( newid )){
					newid=newid+"'";
				}
				
				lay.setId(newid);
				layoutids.add(newid);
				//Add this layout with new id to data-instance
				data.getObjectsAndRelationsAndInformation().add(el);
			}
		}
		**/
		
		//Overwrite layouts with the same name
		for(JAXBElement<?> el:layout.getObjectsAndRelationsAndInformation()){
			if(el.getValue() instanceof LayoutType){
				if( ! replaceGlobalLayout( (LayoutType)el.getValue(), data) ){//If not replaced, insert it
					data.getObjectsAndRelationsAndInformation().add(el);
				}
			}
		}
		
		return data;
	}
	
	/**
	 * Replace a global layout within the lml-model by a new one
	 * @param newlayout new layout, which replaces the old in model with the same id
	 * @param model lgui-instance, which is changed
	 */
	public static boolean replaceGlobalLayout(LayoutType newlayout, LguiType model){
		
		List<JAXBElement<?>> all=model.getObjectsAndRelationsAndInformation();
		
		//Go through all objects, search for layouttypes with newlayout.getId as id and replace them with this layout
		for(int i=0; i<all.size(); i++){
			JAXBElement<?> aobj=all.get(i);
			if(aobj.getValue() instanceof LayoutType){
				LayoutType old=(LayoutType) aobj.getValue();
				if(old.getId().equals(newlayout.getId())){
					( (JAXBElement<LayoutType>)aobj).setValue( newlayout );
					return true;
				}
			}
		}
		
		return false;
	}
	
	
	
	/**
	 * Search for gid-attributes of a pane and put it into neededComponents
	 * Recursively search all graphical objects referenced by this pane
	 * 
	 * @param p part of SplitLayout, which is scanned for gid-attributes
	 * @param neededComponents resulting Hashset
	 */
	private static void collectComponents(PaneType p, HashSet<String> neededComponents){
		
		if(p.getGid()!=null)
			neededComponents.add(p.getGid());
		else{
			//top and bottom components?
			if(p.getBottom()!=null){
				collectComponents(p.getBottom(), neededComponents);
				collectComponents(p.getTop(), neededComponents);
			}
			else{//Left and right
				collectComponents(p.getLeft(), neededComponents);
				collectComponents(p.getRight(), neededComponents);
			}
		}
		
	}
	
	/**
	 * @param gobj
	 * @return a copy of gobj with minimal size, only attributes in GobjectType are copied 
	 * 			 and lower special elements which are needed to make lml-model valid
	 */
	private static JAXBElement<GobjectType> minimizeGobjectType(GobjectType gobj){
		
		String qname="table";
		Class<GobjectType> c=(Class<GobjectType>)gobj.getClass();		
		
		GobjectType value=objectFactory.createGobjectType();
		
		if( gobj instanceof TableType ){
			TableType tt=objectFactory.createTableType();
			
			value=tt;
			
			qname="table";
		}
		else if(gobj instanceof UsagebarType){
			UsagebarType ut=objectFactory.createUsagebarType();
			
			value=ut;
			
			qname="usagebar";
		}
		else if(gobj instanceof TextboxType){
			TextboxType ut=objectFactory.createTextboxType();
			
			value=ut;
			
			qname="text";
		}
		else if(gobj instanceof InfoboxType){
			InfoboxType ut=objectFactory.createInfoboxType();
			
			value=ut;
			
			qname="infobox";
		}
		else if(gobj instanceof Nodedisplay){//Create minimal nodedisplay
			Nodedisplay ut=objectFactory.createNodedisplay();
			
			value=ut;
			SchemeType scheme=objectFactory.createSchemeType();
			scheme.getEl1().add(objectFactory.createSchemeElement1());
			ut.setScheme(scheme);
			
			DataType dat=objectFactory.createDataType();
			dat.getEl1().add(objectFactory.createDataElement1());
			ut.setData(dat);
			
			qname="nodedisplay";
		}
		else if(gobj instanceof ChartType){
			ChartType ut=objectFactory.createChartType();
			
			value=ut;
			
			qname="chart";
		}
		else if(gobj instanceof ChartgroupType){
			ChartgroupType ut=objectFactory.createChartgroupType();
			
			value=ut;
			
			qname="chartgroup";
		}
		
		value.setDescription(gobj.getDescription());
		value.setId(gobj.getId());
		value.setTitle(gobj.getTitle());
		
		
		JAXBElement<GobjectType> res=new JAXBElement<GobjectType>(new QName(qname), c, value  );
		
		return res;
	}
	
	
	/**
	 * Remove all important data from modell
	 * return only layout-information and data, which is needed to make 
	 * lml-model valid
	 * @param modell lml-modell with data and layout-information
	 * @return
	 */
	public static LguiType getLayoutFromModell(LguiType modell){
		
		LguiType res=objectFactory.createLguiType();
		
		HashSet<String> neededComponents=new HashSet<String>();
		
		for(JAXBElement<?> tag: modell.getObjectsAndRelationsAndInformation()){
			
			Object value=tag.getValue();
			
			//add normal global layouts 
			if(value instanceof LayoutType){
				res.getObjectsAndRelationsAndInformation().add(tag);
				
				if(value instanceof SplitlayoutType){
					SplitlayoutType splitlayout=(SplitlayoutType)value;
					//Collect needed components from layout recursively
					if(splitlayout.getLeft()!=null){
						collectComponents(splitlayout.getLeft(), neededComponents);
						collectComponents(splitlayout.getRight(), neededComponents);
					}
				}
				else if(value instanceof AbslayoutType){
					
					AbslayoutType abslayout=(AbslayoutType)value;
					//Just traverse comp-list for gid-attributes
					for(ComponentType comp: abslayout.getComp()){
						neededComponents.add(comp.getGid());
					}
					
				}
				
			}
			else if(value instanceof ComponentlayoutType){
				res.getObjectsAndRelationsAndInformation().add(tag);
				
				ComponentlayoutType complayout=(ComponentlayoutType)value;
				neededComponents.add(complayout.getGid());
			}
			
		}
		
		HashMap<String, GobjectType> idtoGobject=new HashMap<String, GobjectType>();
		//Search needed components in data-tag to discover, which type the needed components have
		for(JAXBElement<?> tag: modell.getObjectsAndRelationsAndInformation()){
			
			Object value=tag.getValue();
			//is it a graphical object?
			if(value instanceof GobjectType){
				GobjectType gobj=(GobjectType)value;
				if(neededComponents.contains(gobj.getId())){
					idtoGobject.put(gobj.getId(), gobj);
				}
			}
		}
		
		//Add all gobjects in idtoGobject to the result, so that lml-modell is valid
		for(GobjectType gobj: idtoGobject.values()){
			JAXBElement<GobjectType> min=minimizeGobjectType(gobj);
			res.getObjectsAndRelationsAndInformation().add(min);
		}
		
		//Set layout-attribute
		res.setLayout(true);
		
		return res;
	}
	
	/**
	 * @param obj LguiType-instance
	 * @param output OutputStream to save xml-representation of obj in
	 * @throws JAXBException 
	 */
	public static void objToLML(LguiType obj, OutputStream output) throws JAXBException {

		JAXBContext jc = JAXBContext.newInstance("lml");
		
		Marshaller mar=jc.createMarshaller();
		
		mar.setProperty("jaxb.schemaLocation", "http://www.llview.de lgui.xsd");
		
		QName tagname=new QName("http://www.llview.de", "lgui", "lml");
		
		JAXBElement<LguiType> rootel=new JAXBElement<LguiType>(tagname, LguiType.class, obj);
		
		mar.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
		
		mar.marshal(rootel, output);
	}	

	/**
	 * Search in component-layouts for layout for the graphical object with id gid.
	 * @param gid id of corresponding graphical object, for which layouts are searched
	 * @return list of componentlayouts corresponding to the graphical object id gid
	 */
	public List<ComponentlayoutType> getComponentLayoutByGID(String gid){
		
		List<ComponentlayoutType> complayouts= getComponentLayouts();
		
		ArrayList<ComponentlayoutType> res=new ArrayList<ComponentlayoutType>();
		
		for(ComponentlayoutType alayout: complayouts){
				
				if( alayout.getGid()!=null && alayout.getGid().equals(gid) ){
					
					res.add(alayout);					
				}
		}
		
		return res;
	}
	
	/**
	 * Add a new created layout to the model
	 * @param layout absolute or splitlayout
	 */
	public void addLayoutTag(LayoutType layout){
		
		if(layout.getId()==null){
			layout.setId("");
		}
		
		JAXBElement<? extends LayoutType> jaxbel=null;
		//Create jaxbelement corresponding to the class-type
		if(layout instanceof AbslayoutType){
			
			AbslayoutType abslayout=(AbslayoutType)layout;
			
			jaxbel=new JAXBElement<AbslayoutType>(new QName("abslayout"), AbslayoutType.class, abslayout);
			
		}
		else
		if(layout instanceof SplitlayoutType){
			
			SplitlayoutType splitlayout=(SplitlayoutType)layout;
			
			jaxbel=new JAXBElement<SplitlayoutType>(new QName("splitlayout"), SplitlayoutType.class, splitlayout);
			
		}
		else
			return;
			
		this.lgui.getObjectsAndRelationsAndInformation().add( jaxbel );
		
		if( lguiItem instanceof LguiItem){
			LguiItem internal=(LguiItem) lguiItem;
			
			internal.updateData(lgui);
		}
			
	}
	
	/**
	 * Generates an absolute layout without needing a layout tag. Active components
	 * are placed in a grid on the screen. Use this function, if no layout was specified
	 * by the lml-file.
	 * @param width width in pixels of the area, on which this layout is shown
	 * @param height height in pixels of the area, on which this layout is shown
	 * @return default absolute layout with all active components in it
	 */
	public AbslayoutType generateDefaultAbsoluteLayout(int width, int height){
		
		//Collect active components
		List<GobjectType> gobjects=lguiItem.getOverviewAccess().getGraphicalObjects();
		
		ArrayList<GobjectType> activeobjects=new ArrayList<GobjectType>();
		//Go through all graphical objects
		for(GobjectType gobj: gobjects){
			//Get layouts for this object, normally there is only one
			List<ComponentlayoutType> layouts=getComponentLayoutByGID(gobj.getId());
			
			if(layouts.size()==0){//assume gobj to be active if there is no componentlayout
				activeobjects.add(gobj);
			}
			
			//Search for a componentlayout which declares gobj to be active
			for(ComponentlayoutType complayout: layouts){
				if( complayout.isActive() ){
					activeobjects.add(gobj);
				}					
			}
		}
		
		//Now activeobjects contains all active graphical objects, which have to be arranged on the screen
		
		AbslayoutType res=objectFactory.createAbslayoutType();
		
		res.setId("abs_default");
		
		//Try to create as many columns as rows
		int columns=(int)Math.round( Math.sqrt( activeobjects.size() ) );
		
		if(columns==0)
			columns=1;
		
		int rows=(int)Math.ceil( (double)activeobjects.size()/columns );
		
		if(rows==0)
			rows=1;
		//Calculate width and height of graphical objects
		int index=0;
		int rectwidth=width/columns;
		int rectheight=height/rows;
		
		for(GobjectType gobj:activeobjects){
			
			ComponentType pos=objectFactory.createComponentType();
			pos.setGid(gobj.getId());
			//Positioning the component
			pos.setW(BigInteger.valueOf(rectwidth));
			pos.setH(BigInteger.valueOf(rectheight));

			pos.setX( BigInteger.valueOf( (index%columns)*rectwidth )) ;
			pos.setY( BigInteger.valueOf( (index/columns)*rectheight )) ;
			
			//Add this component position to the layout
			res.getComp().add(pos);
			
			index++;
		}
		
		return res;
	}
	
	public TablelayoutType getDefaultTableLayout(TableType table) {
		String id = table.getId();
		if (getTableLayout(id) == null || getTableLayout(id).getColumn().size() <= 0) {
			getTableLayout(id).setId(table.getId()+"_layout");
			getTableLayout(id).setGid(table.getId());
			for (int i = 0; i < table.getColumn().size(); i++) {
				ColumnlayoutType column = new ColumnlayoutType();
				column.setCid(BigInteger.valueOf(i + 1));
				column.setPos(BigInteger.valueOf(i));
				column.setWidth(Double.valueOf(1));
				column.setActive(true);
				column.setKey(table.getColumn().get(i).getName());
				getTableLayout(id).getColumn().add(column);
			}
		}
		return getTableLayout(id);
	}
	
	/**
	 * Getting a list of all elements of type ComponentlayoutType from LguiType.
	 * @return list of elements(ComponentlayoutType)
	 */
	List<ComponentlayoutType> getComponentLayouts() {
		List<ComponentlayoutType> layouts = new LinkedList<ComponentlayoutType>();
		for (JAXBElement<?> tag : lgui.getObjectsAndRelationsAndInformation()) {
			if (tag.getValue() instanceof ComponentlayoutType) {
				layouts.add((ComponentlayoutType) tag.getValue());
			}
		}
		return layouts;
	}
	
	/**
	 * Getting a list of elements of type NodedisplaylayoutType.
	 * @return list of elements(NodedisplaylayoutType)
	 */
	List<NodedisplaylayoutType> getNodedisplayLayouts() {
		List<NodedisplaylayoutType> nodedisplayLayouts = new LinkedList<NodedisplaylayoutType>();
		for (ComponentlayoutType tag : getComponentLayouts()) {
			if (tag instanceof NodedisplaylayoutType) {
				nodedisplayLayouts.add((NodedisplaylayoutType) tag);
			}
		}
		return nodedisplayLayouts;
	}
	

	/**
	 * Getting a list of all elements of type TablelayoutType.
	 * @return list of elements(TablelayoutType)
	 */
	List<TablelayoutType> getTableLayouts() {
		List<TablelayoutType> tableLayouts = new LinkedList<TablelayoutType>();
		for (ComponentlayoutType tag : getComponentLayouts()) {
			if (tag instanceof TablelayoutType) {
				tableLayouts.add((TablelayoutType) tag);
			}
		}
		return tableLayouts;
	}
	
	/**
	 * Getting the layout of a given table, the identifier of the layout is the shared ID of table and layout.
	 * @param tablelayoutID ID of the desired tablelayout
	 * @return Corresponding layout of a table
	 */
	public TablelayoutType getTableLayout(String tablelayoutID) {
		for (TablelayoutType tag : getTableLayouts()) {
			if (tag.getGid().equals(tablelayoutID)) {
				return tag;
			}
		}
		return defaultTable;
	}
	

	List<UsagebarlayoutType> getUsagebarLayouts() {
		List<UsagebarlayoutType> usagebarLayouts = new LinkedList<UsagebarlayoutType>();
		for (ComponentlayoutType tag : getComponentLayouts()) {
			if (tag instanceof UsagebarlayoutType) {
				usagebarLayouts.add((UsagebarlayoutType) tag);
			}
		}
		return usagebarLayouts;
	}
	

	List<ChartlayoutType> getChartLayouts() {
		List<ChartlayoutType> chartLayouts = new LinkedList<ChartlayoutType>();
		for (ComponentlayoutType tag : chartLayouts) {
			if (tag instanceof ChartlayoutType) {
				chartLayouts.add((ChartlayoutType) tag);
			}
		}
		return chartLayouts;
	}
	
}
