/**
 * 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.osbp.mysmartshop.dtos.mapper;

import org.eclipse.osbp.dsl.dto.lib.MappingContext;
import org.osbp.mysmartshop.dtos.AddressDto;
import org.osbp.mysmartshop.dtos.CompanyDto;
import org.osbp.mysmartshop.dtos.DepartmentDto;
import org.osbp.mysmartshop.dtos.mapper.BaseUUIDDtoMapper;
import org.osbp.mysmartshop.entities.Address;
import org.osbp.mysmartshop.entities.Company;
import org.osbp.mysmartshop.entities.Department;

/**
 * This class maps the dto {@link AddressDto} to and from the entity {@link Address}.
 * 
 */
@SuppressWarnings("all")
public class AddressDtoMapper<DTO extends AddressDto, ENTITY extends Address> extends BaseUUIDDtoMapper<DTO, ENTITY> {
  /**
   * Creates a new instance of the entity
   */
  public Address createEntity() {
    return new Address();
  }
  
  /**
   * Creates a new instance of the dto
   */
  public AddressDto createDto() {
    return new AddressDto();
  }
  
  /**
   * Maps the entity {@link Address} to the dto {@link AddressDto}.
   * 
   * @param dto - The target dto
   * @param entity - The source entity
   * @param context - The context to get information about depth,...
   * 
   */
  public void mapToDTO(final AddressDto dto, final Address 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.setCompany(toDto_company(entity, context));
    dto.setDepartment(toDto_department(entity, context));
    dto.setAddress1(toDto_address1(entity, context));
    dto.setAddress2(toDto_address2(entity, context));
    dto.setCity(toDto_city(entity, context));
    dto.setState_province(toDto_state_province(entity, context));
    dto.setPostal_code(toDto_postal_code(entity, context));
    dto.setCountry(toDto_country(entity, context));
    dto.setEmail(toDto_email(entity, context));
    dto.setLandline(toDto_landline(entity, context));
    dto.setMobile(toDto_mobile(entity, context));
  }
  
  /**
   * Maps the dto {@link AddressDto} to the entity {@link Address}.
   * 
   * @param dto - The source dto
   * @param entity - The target entity
   * @param context - The context to get information about depth,...
   * 
   */
  public void mapToEntity(final AddressDto dto, final Address 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.setCompany(toEntity_company(dto, entity, context));
    entity.setDepartment(toEntity_department(dto, entity, context));
    entity.setAddress1(toEntity_address1(dto, entity, context));
    entity.setAddress2(toEntity_address2(dto, entity, context));
    entity.setCity(toEntity_city(dto, entity, context));
    entity.setState_province(toEntity_state_province(dto, entity, context));
    entity.setPostal_code(toEntity_postal_code(dto, entity, context));
    entity.setCountry(toEntity_country(dto, entity, context));
    entity.setEmail(toEntity_email(dto, entity, context));
    entity.setLandline(toEntity_landline(dto, entity, context));
    entity.setMobile(toEntity_mobile(dto, entity, context));
  }
  
  /**
   * Maps the property company 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 CompanyDto toDto_company(final Address in, final MappingContext context) {
    if(in.getCompany() != null) {
    	// find a mapper that knows how to map the concrete input type.
    	org.eclipse.osbp.dsl.dto.lib.IMapper<CompanyDto, Company> mapper = (org.eclipse.osbp.dsl.dto.lib.IMapper<CompanyDto, Company>) getToDtoMapper(CompanyDto.class, in.getCompany().getClass());
    	if(mapper == null) {
    		throw new IllegalStateException("Mapper must not be null!");
    	}
    	CompanyDto dto = null;
    	dto = context.get(mapper.createDtoHash(in.getCompany()));
    	if(dto != null) {
    		if(context.isRefresh()){
    			mapper.mapToDTO(dto, in.getCompany(), context);
    		}
    		return dto;
    	}
    	
    	context.increaseLevel();
    	dto = mapper.createDto();
    	mapper.mapToDTO(dto, in.getCompany(), context);
    	context.decreaseLevel();
    	return dto;
    } else {
    	return null;
    }
  }
  
  /**
   * Maps the property company 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 Company toEntity_company(final AddressDto in, final Address parentEntity, final MappingContext context) {
    if(in.getCompany() != null) {
    	// find a mapper that knows how to map the concrete input type.
    	org.eclipse.osbp.dsl.dto.lib.IMapper<CompanyDto, Company> mapper = (org.eclipse.osbp.dsl.dto.lib.IMapper<CompanyDto, Company>) getToEntityMapper(in.getCompany().getClass(), Company.class);
    	if(mapper == null) {
    		throw new IllegalStateException("Mapper must not be null!");
    	}
    
    	Company entity = null;
    	entity = context.get(mapper.createEntityHash(in.getCompany()));
    	if(entity != null) {
    		return entity;
    	} else {
    		entity = (Company) context
    			.findEntityByEntityManager(Company.class, in.getCompany().getId());
    		if (entity != null) {
    			context.register(mapper.createEntityHash(in.getCompany()), entity);
    			return entity;
    		}
    	}
    
    	entity = mapper.createEntity();
    	mapper.mapToEntity(in.getCompany(), entity, context);	
    	return entity;
    } else {
    	return null;
    }	
  }
  
  /**
   * Maps the property department 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 DepartmentDto toDto_department(final Address in, final MappingContext context) {
    if(in.getDepartment() != null) {
    	// find a mapper that knows how to map the concrete input type.
    	org.eclipse.osbp.dsl.dto.lib.IMapper<DepartmentDto, Department> mapper = (org.eclipse.osbp.dsl.dto.lib.IMapper<DepartmentDto, Department>) getToDtoMapper(DepartmentDto.class, in.getDepartment().getClass());
    	if(mapper == null) {
    		throw new IllegalStateException("Mapper must not be null!");
    	}
    	DepartmentDto dto = null;
    	dto = context.get(mapper.createDtoHash(in.getDepartment()));
    	if(dto != null) {
    		if(context.isRefresh()){
    			mapper.mapToDTO(dto, in.getDepartment(), context);
    		}
    		return dto;
    	}
    	
    	context.increaseLevel();
    	dto = mapper.createDto();
    	mapper.mapToDTO(dto, in.getDepartment(), context);
    	context.decreaseLevel();
    	return dto;
    } else {
    	return null;
    }
  }
  
  /**
   * Maps the property department 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 Department toEntity_department(final AddressDto in, final Address parentEntity, final MappingContext context) {
    if(in.getDepartment() != null) {
    	// find a mapper that knows how to map the concrete input type.
    	org.eclipse.osbp.dsl.dto.lib.IMapper<DepartmentDto, Department> mapper = (org.eclipse.osbp.dsl.dto.lib.IMapper<DepartmentDto, Department>) getToEntityMapper(in.getDepartment().getClass(), Department.class);
    	if(mapper == null) {
    		throw new IllegalStateException("Mapper must not be null!");
    	}
    
    	Department entity = null;
    	entity = context.get(mapper.createEntityHash(in.getDepartment()));
    	if(entity != null) {
    		return entity;
    	} else {
    		entity = (Department) context
    			.findEntityByEntityManager(Department.class, in.getDepartment().getId());
    		if (entity != null) {
    			context.register(mapper.createEntityHash(in.getDepartment()), entity);
    			return entity;
    		}
    	}
    
    	entity = mapper.createEntity();
    	mapper.mapToEntity(in.getDepartment(), entity, context);	
    	return entity;
    } else {
    	return null;
    }	
  }
  
  /**
   * Maps the property address1 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_address1(final Address in, final MappingContext context) {
    return in.getAddress1();
  }
  
  /**
   * Maps the property address1 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_address1(final AddressDto in, final Address parentEntity, final MappingContext context) {
    return in.getAddress1();
  }
  
  /**
   * Maps the property address2 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_address2(final Address in, final MappingContext context) {
    return in.getAddress2();
  }
  
  /**
   * Maps the property address2 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_address2(final AddressDto in, final Address parentEntity, final MappingContext context) {
    return in.getAddress2();
  }
  
  /**
   * Maps the property city 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_city(final Address in, final MappingContext context) {
    return in.getCity();
  }
  
  /**
   * Maps the property city 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_city(final AddressDto in, final Address parentEntity, final MappingContext context) {
    return in.getCity();
  }
  
  /**
   * Maps the property state_province 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_state_province(final Address in, final MappingContext context) {
    return in.getState_province();
  }
  
  /**
   * Maps the property state_province 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_state_province(final AddressDto in, final Address parentEntity, final MappingContext context) {
    return in.getState_province();
  }
  
  /**
   * Maps the property postal_code 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_postal_code(final Address in, final MappingContext context) {
    return in.getPostal_code();
  }
  
  /**
   * Maps the property postal_code 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_postal_code(final AddressDto in, final Address parentEntity, final MappingContext context) {
    return in.getPostal_code();
  }
  
  /**
   * Maps the property country 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_country(final Address in, final MappingContext context) {
    return in.getCountry();
  }
  
  /**
   * Maps the property country 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_country(final AddressDto in, final Address parentEntity, final MappingContext context) {
    return in.getCountry();
  }
  
  /**
   * Maps the property email 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_email(final Address in, final MappingContext context) {
    return in.getEmail();
  }
  
  /**
   * Maps the property email 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_email(final AddressDto in, final Address parentEntity, final MappingContext context) {
    return in.getEmail();
  }
  
  /**
   * Maps the property landline 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_landline(final Address in, final MappingContext context) {
    return in.getLandline();
  }
  
  /**
   * Maps the property landline 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_landline(final AddressDto in, final Address parentEntity, final MappingContext context) {
    return in.getLandline();
  }
  
  /**
   * Maps the property mobile 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_mobile(final Address in, final MappingContext context) {
    return in.getMobile();
  }
  
  /**
   * Maps the property mobile 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_mobile(final AddressDto in, final Address parentEntity, final MappingContext context) {
    return in.getMobile();
  }
  
  public String createDtoHash(final Object in) {
    return org.eclipse.osbp.runtime.common.hash.HashUtil.createObjectWithIdHash(AddressDto.class, in);
  }
  
  public String createEntityHash(final Object in) {
    return org.eclipse.osbp.runtime.common.hash.HashUtil.createObjectWithIdHash(Address.class, in);
  }
}
