/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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 org.apache.openmeetings.db.dao.calendar;

import static org.apache.openmeetings.util.OpenmeetingsVariables.webAppRootKey;

import java.util.Date;
import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.NoResultException;
import javax.persistence.PersistenceContext;
import javax.persistence.TypedQuery;

import org.apache.openmeetings.db.dao.user.UserDao;
import org.apache.openmeetings.db.entity.calendar.AppointmentReminderTyps;
import org.red5.logging.Red5LoggerFactory;
import org.slf4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;

@Transactional
public class AppointmentReminderTypDao {
	private static final Logger log = Red5LoggerFactory.getLogger(AppointmentReminderTypDao.class, webAppRootKey);

	@PersistenceContext
	private EntityManager em;
	@Autowired
	private UserDao usersDao;

	public AppointmentReminderTyps get(Long typId) {
		try {
			log.debug("AppointmentReminderTypById: " + typId);

			String hql = "select app from AppointmentReminderTyps app "
					+ "WHERE app.deleted <> :deleted "
					+ "AND app.typId = :typId";

			TypedQuery<AppointmentReminderTyps> query = em.createQuery(hql, AppointmentReminderTyps.class);
			query.setParameter("deleted", true);
			query.setParameter("typId", typId);

			AppointmentReminderTyps appointmentReminderTyps = null;
			try {
				appointmentReminderTyps = query.getSingleResult();
			} catch (NoResultException ex) {
			}

			return appointmentReminderTyps;
		} catch (Exception ex2) {
			log.error("[getAppointmentReminderTypsById]: " + ex2);
		}
		return null;
	}

	public Long updateAppointmentReminderTyps(Long typId, String name) {
		try {

			AppointmentReminderTyps ac = this
					.get(typId);

			ac.setName(name);
			ac.setUpdatetime(new Date());

			if (ac.getTypId() == null) {
				em.persist(ac);
			} else {
				if (!em.contains(ac)) {
					em.merge(ac);
				}
			}

			return typId;
		} catch (Exception ex2) {
			log.error("[updateAppointmentReminderTyps]: ", ex2);
		}
		return null;
	}

	public Long addAppointmentReminderTyps(Long user_id, String name, long fieldvalues_id) {
		try {

			AppointmentReminderTyps ac = new AppointmentReminderTyps();

			ac.setName(name);
			ac.setStarttime(new Date());
			ac.setDeleted(false);
			ac.setUser(usersDao.get(user_id));
			ac.setFieldvalues_id(fieldvalues_id);

			ac = em.merge(ac);
			Long category_id = ac.getTypId();

			return category_id;
		} catch (Exception ex2) {
			log.error("[addAppointmentReminderTyps]: ", ex2);
		}
		return null;
	}

	public Long deleteAppointmentReminderTyp(Long typId) {
		try {

			AppointmentReminderTyps ac = this
					.get(typId);

			log.debug("ac: " + ac);

			if (ac == null) {
				log.debug("Already deleted / Could not find: " + typId);
				return typId;
			}
			ac.setUpdatetime(new Date());
			ac.setDeleted(true);

			if (ac.getTypId() == null) {
				em.persist(ac);
			} else {
				if (!em.contains(ac)) {
					em.merge(ac);
				}
			}

			return typId;
		} catch (Exception ex2) {
			log.error("[deleteAppointmentReminderTyp]: " + ex2);
		}
		return null;
	}

	public List<AppointmentReminderTyps> getAppointmentReminderTypList(long language_id) {
		log.debug("getAppointmenetReminderTypList");

		try {

			String hql = "select a from AppointmentReminderTyps a WHERE a.deleted <> :deleted ";

			TypedQuery<AppointmentReminderTyps> query = em.createQuery(hql, AppointmentReminderTyps.class);
			query.setParameter("deleted", true);

			List<AppointmentReminderTyps> listAppointmentReminderTyp = query.getResultList();

			return listAppointmentReminderTyp;
		} catch (Exception ex2) {
			log.error("[getAppointmentReminderTypList]: " + ex2);
		}
		return null;
	}
}
