/**
 *                                                                            
 *  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.xtext.datamart.common.olap;

import java.util.ArrayList;
import java.util.List;
import java.util.ListIterator;
import java.util.Locale;

import mondrian.olap.Member;

public class DerivedPosition {
	private DerivedCellSet container;
	private org.olap4j.Position olapPosition = null;
	private List<DerivedMember> memberList = new ArrayList<DerivedMember>();
	private int ordinal;
	
	public DerivedPosition(org.olap4j.Position olapPosition, DerivedCellSet container) {
		super();
		setContainer(container);
		this.olapPosition = olapPosition;
		for (org.olap4j.metadata.Member olapMember : olapPosition.getMembers()) {
			memberList.add(new DerivedMember(olapMember));
		}
	}
	public DerivedPosition(mondrian.olap.Position mondrianPosition, int ordinal, DerivedCellSet container) {
		super();
		setContainer(container);
		this.ordinal = ordinal;
//		this.mondrianPosition = mondrianPosition;
		for (ListIterator<Member> iterator = mondrianPosition.listIterator();iterator.hasNext();) {
			mondrian.olap.Member mondrianMember = (mondrian.olap.Member) iterator.next();
			memberList.add(new DerivedMember(mondrianMember));
		}
	}
	
	public DerivedCellSet getContainer() {
		return container;
	}
	public void setContainer(DerivedCellSet container) {
		this.container = container;
	}
	public DerivedPosition(String taskPosition, int ordinal, DerivedCellSet container) {
		super();
		setContainer(container);
		this.ordinal = ordinal;
//		this.taskPosition = taskPosition;
		memberList.add(new DerivedMember(taskPosition));
	}

	// dummy position
	public DerivedPosition(List<DerivedMember> memberList, int ordinal, DerivedCellSet container) {
		super();
		setContainer(container);
		this.ordinal = ordinal;
		this.memberList = memberList;
	}

	public List<DerivedMember> getMembers(){
		return memberList;
	}
	
	public int getOrdinal(){
		if (olapPosition != null) {
			return olapPosition.getOrdinal();
		} else {
			return ordinal;
		}
	}

	private String getTranslatedColumnHeader(Locale locale) {
		String hdr = getColumnHeader(true, locale);
		if(hdr != null) {
			return hdr.replace(" ", "&nbsp;");
		}
		return hdr;
	}

	private String getColumnHeader() {
		return getColumnHeader(false, null);
	}
	
	private String getColumnHeader(boolean withBreaks, Locale locale) {
		String header = null;
		for (DerivedMember member : getMembers()) {
			String headerPart = "";
			if (getOrdinal() < 0) {
				List<String>colHeaders = new ArrayList<String>();
				DerivedHierarchy hier = null;
				hier = member.getHierarchy();
				if (hier != null) {
		    		for(DerivedLevel lev : hier.getLevels()) {
		    			if(!lev.isAll() && lev.isVisible()) { 
		    				if(locale != null) {
		    					colHeaders.add(container.getDSLMetadataService().translate(locale.toLanguageTag(), lev.getName()));
		    				} else {
		    					colHeaders.add(lev.getName());
		    				}
		    			}
		    		}
				}
				int index = -1*(getOrdinal()+1);
				if(index < colHeaders.size() && index >= 0) {
					headerPart = colHeaders.get(index);
				}
			}
			else {
				if(locale != null) {
					headerPart = container.getDSLMetadataService().translate(locale.toLanguageTag(), member.getCaption());
				} else {
					headerPart = member.getCaption();
				}
			}
			if (header == null) {
				header = headerPart;
			} else {
				if (withBreaks) {
					headerPart = "<br>"+headerPart;
				}
				header += headerPart;
			}
		}
		return header;
	}
	
	public String toString(Locale locale) {
		return getTranslatedColumnHeader(locale);
	}

	public String toUnformattedString() {
		return getColumnHeader();
	}

	public String toUppercaseString() {
		return getColumnHeader().toUpperCase();
	}
}
