/**
 *                                                                            
 *  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 v1.0       
 *  which accompanies this distribution, and is available at                  
 *  http://www.eclipse.org/legal/epl-v10.html                                 
 *                                                                            
 *  Contributors:                                                      
 * 	   Christophe Loetz (Loetz GmbH&Co.KG) - initial implementation
 * 
 */
 package org.eclipse.osbp.xtext.functionlibrarydsl.util;

import java.util.HashMap;
import java.util.Map;

import org.eclipse.osbp.ui.api.user.IUser;
import org.eclipse.osbp.xtext.datamart.common.olap.DerivedPosition;
import org.eclipse.osbp.xtext.table.common.PositionInfo;
import org.jbpm.task.Status;
import org.jbpm.task.query.TaskSummary;


public class Library {
	
	public final static class Context extends HashMap<String, Object> {
		private static final long serialVersionUID = -2810090198332954979L;
		
		public final static String USER = "user";
		public final static String TABLE = "table";
		public final static String TASKSUMMARY = "taskSummary";
	}
	
	static boolean toogleState = false; 
	static long lastTime = 0L;
	public static boolean timerToggle(long ms) {
		if (System.currentTimeMillis() - lastTime > ms) {
			lastTime = System.currentTimeMillis();
			toogleState ^= true;
		}
		return toogleState;
	}
	
	public static String getUserName(Context contextMap) {
		if (contextMap != null && contextMap.containsKey(Context.USER)) {
			IUser user = (IUser)contextMap.get(Context.USER);
			return user.getUserName();
		}
		return null;  
	}
	
	public static Object getTableColumnValue(Context contextMap, String columnName) {
		if (columnName != null && contextMap != null && contextMap.containsKey(Context.TABLE)) {
			Map<Integer, PositionInfo> positionMap = (Map<Integer, PositionInfo>) contextMap.get(Context.TABLE);
			for(Integer column : positionMap.keySet()) {
				DerivedPosition pos = positionMap.get(column).getPosition();
				if(pos.toUnformattedString().equalsIgnoreCase(columnName)) {
					return positionMap.get(column).getSelectedValue();
				}
			}
		}
		return null;
	}

	public static long getTaskId(Context contextMap) {
		if (contextMap != null && contextMap.containsKey(Context.TASKSUMMARY)) {
			TaskSummary task = (TaskSummary) contextMap.get(Context.TASKSUMMARY);
			if (task != null) {
				return task.getId();
			}
		}
		return 0;
	}
	
	public static boolean isTask(Context contextMap, Status status) {
		if (contextMap != null && contextMap.containsKey(Context.TASKSUMMARY)) {
			TaskSummary task = (TaskSummary) contextMap.get(Context.TASKSUMMARY);
			if(task != null && task.getStatus() != null && task.getStatus().toString().equalsIgnoreCase(status.toString())) {
				return true;
			}
		}
		return false;
	}
	
	public static Status getStatusType(int code) {
		for(Status type : Status.values()) {
			if(type.ordinal() == code) {
				return type;
			}
		}
		return null;
	}
}
