/**
 * Copyright (c) 2011, 2015 - Lunifera GmbH (Gross Enzersdorf), Loetz GmbH&Co.KG (Heidelberg)
 * 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:
 *         Florian Pirchner - Initial implementation
 */
package org.eclipse.osbp.dsl.tests.carstore.dtos.mapper;

import org.eclipse.osbp.dsl.dto.lib.MappingContext;
import org.eclipse.osbp.dsl.tests.carstore.dtos.CarDto;
import org.eclipse.osbp.dsl.tests.carstore.dtos.ToCycle1Dto;
import org.eclipse.osbp.dsl.tests.carstore.dtos.ToCycle2Dto;
import org.eclipse.osbp.dsl.tests.carstore.dtos.mapper.BaseDtoMapper;
import org.eclipse.osbp.dsl.tests.carstore.entities.Car;
import org.eclipse.osbp.dsl.tests.carstore.entities.ToCycle1;
import org.eclipse.osbp.dsl.tests.carstore.entities.ToCycle2;

/**
 * This class maps the dto {@link ToCycle2Dto} to and from the entity {@link ToCycle2}.
 * 
 */
@SuppressWarnings("all")
public class ToCycle2DtoMapper<DTO extends ToCycle2Dto, ENTITY extends ToCycle2> extends BaseDtoMapper<DTO, ENTITY> {
  /**
   * Creates a new instance of the entity
   */
  public ToCycle2 createEntity() {
    return new ToCycle2();
  }
  
  /**
   * Creates a new instance of the dto
   */
  public ToCycle2Dto createDto() {
    return new ToCycle2Dto();
  }
  
  /**
   * Maps the entity {@link ToCycle2} to the dto {@link ToCycle2Dto}.
   * 
   * @param dto - The target dto
   * @param entity - The source entity
   * @param context - The context to get information about depth,...
   * 
   */
  public void mapToDTO(final ToCycle2Dto dto, final ToCycle2 entity, final MappingContext context) {
    if(context == null){
    	throw new IllegalArgumentException("Please pass a context!");
    }
    context.register(createDtoHash(entity), dto);
    
    super.mapToDTO(dto, entity, context);
    
    dto.setParent(toDto_parent(entity, context));
    dto.setCar(toDto_car(entity, context));
  }
  
  /**
   * Maps the dto {@link ToCycle2Dto} to the entity {@link ToCycle2}.
   * 
   * @param dto - The source dto
   * @param entity - The target entity
   * @param context - The context to get information about depth,...
   * 
   */
  public void mapToEntity(final ToCycle2Dto dto, final ToCycle2 entity, final MappingContext context) {
    if(context == null){
    	throw new IllegalArgumentException("Please pass a context!");
    }
    
    context.register(createEntityHash(dto), entity);
    context.registerMappingRoot(createEntityHash(dto), dto);
    super.mapToEntity(dto, entity, context);
    
    entity.setParent(toEntity_parent(dto, entity, context));
    entity.setCar(toEntity_car(dto, entity, context));
  }
  
  /**
   * Maps the property parent from the given entity to the dto.
   * 
   * @param in - The source entity
   * @param context - The context to get information about depth,...
   * @return the mapped dto
   * 
   */
  protected ToCycle1Dto toDto_parent(final ToCycle2 in, final MappingContext context) {
    if(in.getParent() != null) {
    	// find a mapper that knows how to map the concrete input type.
    	org.eclipse.osbp.dsl.dto.lib.IMapper<ToCycle1Dto, ToCycle1> mapper = (org.eclipse.osbp.dsl.dto.lib.IMapper<ToCycle1Dto, ToCycle1>) getToDtoMapper(ToCycle1Dto.class, in.getParent().getClass());
    	if(mapper == null) {
    		throw new IllegalStateException("Mapper must not be null!");
    	}
    	ToCycle1Dto dto = null;
    	dto = context.get(mapper.createDtoHash(in.getParent()));
    	if(dto != null) {
    		if(context.isRefresh()){
    			mapper.mapToDTO(dto, in.getParent(), context);
    		}
    		return dto;
    	}
    	
    	context.increaseLevel();
    	dto = mapper.createDto();
    	mapper.mapToDTO(dto, in.getParent(), context);
    	context.decreaseLevel();
    	return dto;
    } else {
    	return null;
    }
  }
  
  /**
   * Maps the property parent from the given dto to the entity.
   * 
   * @param in - The source dto
   * @param parentEntity - The parent entity
   * @param context - The context to get information about depth,...
   * @return the mapped entity
   * 
   */
  protected ToCycle1 toEntity_parent(final ToCycle2Dto in, final ToCycle2 parentEntity, final MappingContext context) {
    if(in.getParent() != null) {
    	// find a mapper that knows how to map the concrete input type.
    	org.eclipse.osbp.dsl.dto.lib.IMapper<ToCycle1Dto, ToCycle1> mapper = (org.eclipse.osbp.dsl.dto.lib.IMapper<ToCycle1Dto, ToCycle1>) getToEntityMapper(in.getParent().getClass(), ToCycle1.class);
    	if(mapper == null) {
    		throw new IllegalStateException("Mapper must not be null!");
    	}
    
    	ToCycle1 entity = null;
    	entity = context.get(mapper.createEntityHash(in.getParent()));
    	if(entity != null) {
    		return entity;
    	} else {
    		entity = (ToCycle1) context
    			.findEntityByEntityManager(ToCycle1.class, in.getParent().getUuid());
    		if (entity != null) {
    			context.register(mapper.createEntityHash(in.getParent()), entity);
    			return entity;
    		}
    	}
    
    	entity = mapper.createEntity();
    	mapper.mapToEntity(in.getParent(), entity, context);	
    	return entity;
    } else {
    	return null;
    }	
  }
  
  /**
   * Maps the property car from the given entity to the dto.
   * 
   * @param in - The source entity
   * @param context - The context to get information about depth,...
   * @return the mapped dto
   * 
   */
  protected CarDto toDto_car(final ToCycle2 in, final MappingContext context) {
    if(in.getCar() != null) {
    	// find a mapper that knows how to map the concrete input type.
    	org.eclipse.osbp.dsl.dto.lib.IMapper<CarDto, Car> mapper = (org.eclipse.osbp.dsl.dto.lib.IMapper<CarDto, Car>) getToDtoMapper(CarDto.class, in.getCar().getClass());
    	if(mapper == null) {
    		throw new IllegalStateException("Mapper must not be null!");
    	}
    	CarDto dto = null;
    	dto = context.get(mapper.createDtoHash(in.getCar()));
    	if(dto != null) {
    		if(context.isRefresh()){
    			mapper.mapToDTO(dto, in.getCar(), context);
    		}
    		return dto;
    	}
    	
    	context.increaseLevel();
    	dto = mapper.createDto();
    	mapper.mapToDTO(dto, in.getCar(), context);
    	context.decreaseLevel();
    	return dto;
    } else {
    	return null;
    }
  }
  
  /**
   * Maps the property car from the given dto to the entity.
   * 
   * @param in - The source dto
   * @param parentEntity - The parent entity
   * @param context - The context to get information about depth,...
   * @return the mapped entity
   * 
   */
  protected Car toEntity_car(final ToCycle2Dto in, final ToCycle2 parentEntity, final MappingContext context) {
    if(in.getCar() != null) {
    	// find a mapper that knows how to map the concrete input type.
    	org.eclipse.osbp.dsl.dto.lib.IMapper<CarDto, Car> mapper = (org.eclipse.osbp.dsl.dto.lib.IMapper<CarDto, Car>) getToEntityMapper(in.getCar().getClass(), Car.class);
    	if(mapper == null) {
    		throw new IllegalStateException("Mapper must not be null!");
    	}
    
    	Car entity = null;
    	entity = context.get(mapper.createEntityHash(in.getCar()));
    	if(entity != null) {
    		return entity;
    	} else {
    		entity = (Car) context
    			.findEntityByEntityManager(Car.class, in.getCar().getUuid());
    		if (entity != null) {
    			context.register(mapper.createEntityHash(in.getCar()), entity);
    			return entity;
    		}
    	}
    
    	entity = mapper.createEntity();
    	mapper.mapToEntity(in.getCar(), entity, context);	
    	return entity;
    } else {
    	return null;
    }	
  }
  
  public String createDtoHash(final Object in) {
    return org.eclipse.osbp.runtime.common.hash.HashUtil.createObjectWithIdHash(ToCycle2Dto.class, in);
  }
  
  public String createEntityHash(final Object in) {
    return org.eclipse.osbp.runtime.common.hash.HashUtil.createObjectWithIdHash(ToCycle2.class, in);
  }
}
