package org.osbp.tests.dtos.mapper;

import java.util.Date;
import org.eclipse.osbp.dsl.dto.lib.MappingContext;
import org.osbp.tests.dtos.CashPaymentDto;
import org.osbp.tests.dtos.CashPaymentMethodDto;
import org.osbp.tests.dtos.CashSlipDto;
import org.osbp.tests.dtos.mapper.BaseUUIDDtoMapper;
import org.osbp.tests.entities.CashPayment;
import org.osbp.tests.entities.CashPaymentMethod;
import org.osbp.tests.entities.CashSlip;

/**
 * This class maps the dto {@link CashPaymentDto} to and from the entity {@link CashPayment}.
 * 
 */
@SuppressWarnings("all")
public class CashPaymentDtoMapper<DTO extends CashPaymentDto, ENTITY extends CashPayment> extends BaseUUIDDtoMapper<DTO, ENTITY> {
  /**
   * Creates a new instance of the entity
   */
  public CashPayment createEntity() {
    return new CashPayment();
  }
  
  /**
   * Creates a new instance of the dto
   */
  public CashPaymentDto createDto() {
    return new CashPaymentDto();
  }
  
  /**
   * Maps the entity {@link CashPayment} to the dto {@link CashPaymentDto}.
   * 
   * @param dto - The target dto
   * @param entity - The source entity
   * @param context - The context to get information about depth,...
   * 
   */
  public void mapToDTO(final CashPaymentDto dto, final CashPayment 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.setNow(toDto_now(entity, context));
    dto.setPayed(toDto_payed(entity, context));
    dto.setSlip(toDto_slip(entity, context));
    dto.setMethodOfPayment(toDto_methodOfPayment(entity, context));
  }
  
  /**
   * Maps the dto {@link CashPaymentDto} to the entity {@link CashPayment}.
   * 
   * @param dto - The source dto
   * @param entity - The target entity
   * @param context - The context to get information about depth,...
   * 
   */
  public void mapToEntity(final CashPaymentDto dto, final CashPayment 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.setNow(toEntity_now(dto, entity, context));
    entity.setPayed(toEntity_payed(dto, entity, context));
    entity.setSlip(toEntity_slip(dto, entity, context));
    entity.setMethodOfPayment(toEntity_methodOfPayment(dto, entity, context));
  }
  
  /**
   * Maps the property now from the given entity to dto property.
   * 
   * @param in - The source entity
   * @param context - The context to get information about depth,...
   * @return the mapped value
   * 
   */
  protected Date toDto_now(final CashPayment in, final MappingContext context) {
    return in.getNow();
  }
  
  /**
   * Maps the property now from the given entity to dto property.
   * 
   * @param in - The source entity
   * @param parentEntity - The parentEntity
   * @param context - The context to get information about depth,...
   * @return the mapped value
   * 
   */
  protected Date toEntity_now(final CashPaymentDto in, final CashPayment parentEntity, final MappingContext context) {
    return in.getNow();
  }
  
  /**
   * Maps the property payed from the given entity to dto property.
   * 
   * @param in - The source entity
   * @param context - The context to get information about depth,...
   * @return the mapped value
   * 
   */
  protected Double toDto_payed(final CashPayment in, final MappingContext context) {
    return in.getPayed();
  }
  
  /**
   * Maps the property payed from the given entity to dto property.
   * 
   * @param in - The source entity
   * @param parentEntity - The parentEntity
   * @param context - The context to get information about depth,...
   * @return the mapped value
   * 
   */
  protected Double toEntity_payed(final CashPaymentDto in, final CashPayment parentEntity, final MappingContext context) {
    return in.getPayed();
  }
  
  /**
   * Maps the property slip 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 CashSlipDto toDto_slip(final CashPayment in, final MappingContext context) {
    if(in.getSlip() != null) {
    	// find a mapper that knows how to map the concrete input type.
    	org.eclipse.osbp.dsl.dto.lib.IMapper<CashSlipDto, CashSlip> mapper = (org.eclipse.osbp.dsl.dto.lib.IMapper<CashSlipDto, CashSlip>) getToDtoMapper(CashSlipDto.class, in.getSlip().getClass());
    	if(mapper == null) {
    		throw new IllegalStateException("Mapper must not be null!");
    	}
    	CashSlipDto dto = null;
    	dto = context.get(mapper.createDtoHash(in.getSlip()));
    	if(dto != null) {
    		if(context.isRefresh()){
    			mapper.mapToDTO(dto, in.getSlip(), context);
    		}
    		return dto;
    	}
    	
    	context.increaseLevel();
    	dto = mapper.createDto();
    	mapper.mapToDTO(dto, in.getSlip(), context);
    	context.decreaseLevel();
    	return dto;
    } else {
    	return null;
    }
  }
  
  /**
   * Maps the property slip 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 CashSlip toEntity_slip(final CashPaymentDto in, final CashPayment parentEntity, final MappingContext context) {
    if(in.getSlip() != null) {
    	// find a mapper that knows how to map the concrete input type.
    	org.eclipse.osbp.dsl.dto.lib.IMapper<CashSlipDto, CashSlip> mapper = (org.eclipse.osbp.dsl.dto.lib.IMapper<CashSlipDto, CashSlip>) getToEntityMapper(in.getSlip().getClass(), CashSlip.class);
    	if(mapper == null) {
    		throw new IllegalStateException("Mapper must not be null!");
    	}
    
    	CashSlip entity = null;
    	entity = context.get(mapper.createEntityHash(in.getSlip()));
    	if(entity != null) {
    		return entity;
    	} else {
    		entity = (CashSlip) context
    			.findEntityByEntityManager(CashSlip.class, in.getSlip().getId());
    		if (entity != null) {
    			context.register(mapper.createEntityHash(in.getSlip()), entity);
    			return entity;
    		}
    	}
    
    	entity = mapper.createEntity();
    	mapper.mapToEntity(in.getSlip(), entity, context);	
    	return entity;
    } else {
    	return null;
    }	
  }
  
  /**
   * Maps the property methodOfPayment 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 CashPaymentMethodDto toDto_methodOfPayment(final CashPayment in, final MappingContext context) {
    if(in.getMethodOfPayment() != null) {
    	// find a mapper that knows how to map the concrete input type.
    	org.eclipse.osbp.dsl.dto.lib.IMapper<CashPaymentMethodDto, CashPaymentMethod> mapper = (org.eclipse.osbp.dsl.dto.lib.IMapper<CashPaymentMethodDto, CashPaymentMethod>) getToDtoMapper(CashPaymentMethodDto.class, in.getMethodOfPayment().getClass());
    	if(mapper == null) {
    		throw new IllegalStateException("Mapper must not be null!");
    	}
    	CashPaymentMethodDto dto = null;
    	dto = context.get(mapper.createDtoHash(in.getMethodOfPayment()));
    	if(dto != null) {
    		if(context.isRefresh()){
    			mapper.mapToDTO(dto, in.getMethodOfPayment(), context);
    		}
    		return dto;
    	}
    	
    	context.increaseLevel();
    	dto = mapper.createDto();
    	mapper.mapToDTO(dto, in.getMethodOfPayment(), context);
    	context.decreaseLevel();
    	return dto;
    } else {
    	return null;
    }
  }
  
  /**
   * Maps the property methodOfPayment 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 CashPaymentMethod toEntity_methodOfPayment(final CashPaymentDto in, final CashPayment parentEntity, final MappingContext context) {
    if(in.getMethodOfPayment() != null) {
    	// find a mapper that knows how to map the concrete input type.
    	org.eclipse.osbp.dsl.dto.lib.IMapper<CashPaymentMethodDto, CashPaymentMethod> mapper = (org.eclipse.osbp.dsl.dto.lib.IMapper<CashPaymentMethodDto, CashPaymentMethod>) getToEntityMapper(in.getMethodOfPayment().getClass(), CashPaymentMethod.class);
    	if(mapper == null) {
    		throw new IllegalStateException("Mapper must not be null!");
    	}
    
    	CashPaymentMethod entity = null;
    	entity = context.get(mapper.createEntityHash(in.getMethodOfPayment()));
    	if(entity != null) {
    		return entity;
    	} else {
    		entity = (CashPaymentMethod) context
    			.findEntityByEntityManager(CashPaymentMethod.class, in.getMethodOfPayment().getId());
    		if (entity != null) {
    			context.register(mapper.createEntityHash(in.getMethodOfPayment()), entity);
    			return entity;
    		}
    	}
    
    	entity = mapper.createEntity();
    	mapper.mapToEntity(in.getMethodOfPayment(), entity, context);	
    	return entity;
    } else {
    	return null;
    }	
  }
  
  public String createDtoHash(final Object in) {
    return org.eclipse.osbp.runtime.common.hash.HashUtil.createObjectWithIdHash(CashPaymentDto.class, in);
  }
  
  public String createEntityHash(final Object in) {
    return org.eclipse.osbp.runtime.common.hash.HashUtil.createObjectWithIdHash(CashPayment.class, in);
  }
}
