/*
 * Copyright (c) 2010-2013 Evolveum
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.evolveum.midpoint.web.page.admin.users.dto;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

import javax.xml.namespace.QName;

import com.evolveum.midpoint.schema.constants.SchemaConstants;
import org.apache.wicket.model.IModel;
import org.apache.wicket.model.Model;
import org.jvnet.jaxb2_commons.lang.Validate;

import com.evolveum.midpoint.prism.PrismObject;
import com.evolveum.midpoint.schema.result.OperationResult;
import com.evolveum.midpoint.web.component.orgStruct.NodeDto;
import com.evolveum.midpoint.web.component.orgStruct.NodeType;
import com.evolveum.midpoint.xml.ns._public.common.common_2a.ObjectReferenceType;
import com.evolveum.midpoint.xml.ns._public.common.common_2a.ObjectType;
import com.evolveum.midpoint.xml.ns._public.common.common_2a.OrgType;
import com.evolveum.midpoint.xml.ns._public.common.common_2a.UserType;

/**
 * @author mserbak
 */
public class OrgStructDto<T extends ObjectType> implements Serializable {
	private List<NodeDto> orgUnitList;
	private List<NodeDto> userList;
	private OperationResult result = new OperationResult(OrgStructDto.class.getName());

	public OrgStructDto(List<PrismObject<T>> orgUnitList, NodeDto parent) {
		this(orgUnitList, parent, null);
	}
	
	public OrgStructDto(List<PrismObject<T>> orgUnitList, NodeDto parent, OperationResult result) {
		Validate.notNull(orgUnitList);
		if(result != null) {
			this.result = result;
		}
		initNodes(orgUnitList, parent);
	}

	private void initNodes(List<PrismObject<T>> list, NodeDto parent) {
		listNodes:
		for (PrismObject<T> node : list) {
			ObjectType nodeObject = node.asObjectable();

			if (nodeObject instanceof OrgType) {
				if (orgUnitList == null) {
					orgUnitList = new ArrayList<NodeDto>();
				}
				OrgType org = (OrgType) nodeObject;
				orgUnitList.add(new NodeDto(parent, org.getDisplayName().toString(), org.getOid(),
						NodeType.FOLDER));

			} else if (nodeObject instanceof UserType) {
				if (userList == null) {
					userList = new ArrayList<NodeDto>();
				}
				UserType user = (UserType) nodeObject;
				if(!userList.isEmpty()) {
					for (NodeDto userDto : userList) {
						if(userDto.getOid().equals(user.getOid())) {
							userDto.addTypeToListTypes(getRelation(parent, user));
							continue listNodes;
						}
					}
				}
				userList.add(new NodeDto(parent, user.getFullName().toString(), user.getOid(), getRelation(
						parent, user)));
			}
		}
	}

	public IModel<String> getTitle() {
		if (orgUnitList != null && !orgUnitList.isEmpty()) {
			String title = orgUnitList.get(0).getDisplayName().toString();
			return new Model<String>(title);
		}
		return new Model<String>("");
	}

	public List<NodeDto> getOrgUnitDtoList() {
		return orgUnitList;
	}

	public List<NodeDto> getUserDtoList() {
		return userList;
	}

	public NodeType getRelation(NodeDto parent, UserType user) {
		List<ObjectReferenceType> orgRefList = user.getParentOrgRef();
		ObjectReferenceType orgRef = null;

		for (ObjectReferenceType orgRefType : orgRefList) {
			if (orgRefType.getOid()!= null && orgRefType.getOid().equals(parent.getOid())) {
				orgRef = orgRefType;
				break;
			}
		}
		
		if(orgRef == null) {
			OperationResult subresult = result.createSubresult("getRelation - Getting NodeType for node: " + user.getName());
			subresult.recordFatalError("ObjectReferenceType is undefined/incorrect");
			return null;
		}

		if (orgRef.getRelation() == null) {
			return NodeType.MEMBER;
		}
		QName relation = orgRef.getRelation();

		if (SchemaConstants.ORG_MANAGER.equals(relation)) {
			return NodeType.MANAGER;
		}
		return null;
	}

}

@@ -801,39 +801,257 @@
 int.
-schema.constants.SchemaConstant
+prism.polystring.PolyString;%0Aimport com.evolveum.midpoint.schema.constants.SchemaConstants;%0Aimport com.evolveum.midpoint.web.util.WebMiscUtil;%0Aimport com.evolveum.prism.xml.ns._public.types_2.PolyStringType;%0Aimport org.apache.commons.lang.StringUtil
 s;%0Ai
@@ -2662,16 +2662,24 @@
 parent, 
+getName(
 org.getD
@@ -2690,26 +2690,31 @@
 ayName()
-.toString(
+, org.getName()
 ), org.g
@@ -3179,24 +3179,32 @@
 Dto(parent, 
+getName(
 user.getFull
@@ -3209,26 +3209,32 @@
 llName()
-.toString(
+, user.getName()
 ), user.
@@ -3242,16 +3242,40 @@
 etOid(),
+%0A                       
  getRela
@@ -3279,23 +3279,16 @@
 elation(
-%0A%09%09%09%09%09%09
 parent, 
@@ -3305,24 +3305,265 @@
 %09%09%7D%0A%09%09%7D%0A%09%7D%0A%0A
+    private String getName(PolyStringType name, PolyStringType defaultValue) %7B%0A        if (name != null && StringUtils.isNotEmpty(name.getOrig())) %7B%0A            return name.getOrig();%0A        %7D%0A%0A        return defaultValue.getOrig();%0A    %7D%0A%0A
 %09public IMod

fix for org. structure page NPE, MID-1602