package org.eclipse.osbp.blob.dtos.mapper;

import org.eclipse.osbp.blob.dtos.NormalizerResolutionDto;
import org.eclipse.osbp.blob.entities.NormalizerResolution;
import org.eclipse.osbp.dsl.dto.lib.IMapper;
import org.eclipse.osbp.dsl.dto.lib.IMapperAccess;
import org.eclipse.osbp.dsl.dto.lib.MappingContext;

/**
 * This class maps the dto {@link NormalizerResolutionDto} to and from the entity {@link NormalizerResolution}.
 * 
 */
@SuppressWarnings("all")
public class NormalizerResolutionDtoMapper<DTO extends NormalizerResolutionDto, ENTITY extends NormalizerResolution> implements IMapper<DTO, ENTITY> {
  private IMapperAccess mapperAccess;
  
  /**
   * Returns the mapper instance that may map between the given dto and entity. Or <code>null</code> if no mapper is available.
   * 
   * @param dtoClass - the class of the dto that should be mapped
   * @param entityClass - the class of the entity that should be mapped
   * @return the mapper instance or <code>null</code>
   */
  protected <D, E> IMapper<D, E> getToDtoMapper(final Class<D> dtoClass, final Class<E> entityClass) {
    return mapperAccess.getToDtoMapper(dtoClass, entityClass);
  }
  
  /**
   * Returns the mapper instance that may map between the given dto and entity. Or <code>null</code> if no mapper is available.
   * 
   * @param dtoClass - the class of the dto that should be mapped
   * @param entityClass - the class of the entity that should be mapped
   * @return the mapper instance or <code>null</code>
   */
  protected <D, E> IMapper<D, E> getToEntityMapper(final Class<D> dtoClass, final Class<E> entityClass) {
    return mapperAccess.getToEntityMapper(dtoClass, entityClass);
  }
  
  /**
   * Called by OSGi-DS. Binds the mapper access service.
   * 
   * @param service - The mapper access service
   * 
   */
  protected void bindMapperAccess(final IMapperAccess mapperAccess) {
    this.mapperAccess = mapperAccess;
  }
  
  /**
   * Called by OSGi-DS. Binds the mapper access service.
   * 
   * @param service - The mapper access service
   * 
   */
  protected void unbindMapperAccess(final IMapperAccess mapperAccess) {
    this.mapperAccess = null;
  }
  
  /**
   * Creates a new instance of the entity
   */
  public NormalizerResolution createEntity() {
    return new NormalizerResolution();
  }
  
  /**
   * Creates a new instance of the dto
   */
  public NormalizerResolutionDto createDto() {
    return new NormalizerResolutionDto();
  }
  
  /**
   * Maps the entity {@link NormalizerResolution} to the dto {@link NormalizerResolutionDto}.
   * 
   * @param dto - The target dto
   * @param entity - The source entity
   * @param context - The context to get information about depth,...
   * 
   */
  public void mapToDTO(final NormalizerResolutionDto dto, final NormalizerResolution entity, final MappingContext context) {
    if(context == null){
    	throw new IllegalArgumentException("Please pass a context!");
    }
    dto.setId(toDto_id(entity, context));
    dto.setName(toDto_name(entity, context));
    dto.setResolution(toDto_resolution(entity, context));
  }
  
  /**
   * Maps the dto {@link NormalizerResolutionDto} to the entity {@link NormalizerResolution}.
   * 
   * @param dto - The source dto
   * @param entity - The target entity
   * @param context - The context to get information about depth,...
   * 
   */
  public void mapToEntity(final NormalizerResolutionDto dto, final NormalizerResolution entity, final MappingContext context) {
    if(context == null){
    	throw new IllegalArgumentException("Please pass a context!");
    }
    
    
    entity.setId(toEntity_id(dto, entity, context));
    entity.setName(toEntity_name(dto, entity, context));
    entity.setResolution(toEntity_resolution(dto, entity, context));
  }
  
  /**
   * Maps the property id 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 int toDto_id(final NormalizerResolution in, final MappingContext context) {
    return in.getId();
  }
  
  /**
   * Maps the property id 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 int toEntity_id(final NormalizerResolutionDto in, final NormalizerResolution parentEntity, final MappingContext context) {
    return in.getId();
  }
  
  /**
   * Maps the property name 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 String toDto_name(final NormalizerResolution in, final MappingContext context) {
    return in.getName();
  }
  
  /**
   * Maps the property name 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 String toEntity_name(final NormalizerResolutionDto in, final NormalizerResolution parentEntity, final MappingContext context) {
    return in.getName();
  }
  
  /**
   * Maps the property resolution 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 String toDto_resolution(final NormalizerResolution in, final MappingContext context) {
    return in.getResolution();
  }
  
  /**
   * Maps the property resolution 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 String toEntity_resolution(final NormalizerResolutionDto in, final NormalizerResolution parentEntity, final MappingContext context) {
    return in.getResolution();
  }
  
  public String createDtoHash(final Object in) {
    throw new UnsupportedOperationException("No id attribute available");
  }
  
  public String createEntityHash(final Object in) {
    throw new UnsupportedOperationException("No id attribute available");
  }
}
