/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.dhaval.web.vaadin.simple.domain;

import com.dhaval.web.vaadin.simple.EntryPoint.LoginDetail;
import com.google.appengine.api.datastore.DatastoreService;
import com.google.appengine.api.datastore.DatastoreServiceFactory;
import com.google.appengine.api.datastore.Entity;
import com.google.appengine.api.datastore.PreparedQuery;
import com.google.appengine.api.datastore.Query;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 *  The class needs a lot of refactoring
 *
 *  Last Updated: 25-Aug-2010
 *
 * @author dhaval
 */
public class FormsContainer implements Serializable{

    private List<Form> formList = new ArrayList<Form>();
    private List<FormListener> listeners = new ArrayList<FormListener>();
    private Map<String, List<Map<String, Object>>> formDataList = new HashMap<String, List<Map<String, Object>>>();

    private LoginDetail user;

    public FormsContainer(LoginDetail user) {
        this.user = user;
        
        updateFormList();
    }

    public List<Form> getAvailableForms() {
        return formList;
    }

    private List<Form> updateFormList() {
        try{
            formList.clear();
            DatastoreService datastore = DatastoreServiceFactory.getDatastoreService();
            Query formQuery = new Query("form");
            formQuery.addFilter("user", Query.FilterOperator.EQUAL, user.getUserId());
            PreparedQuery query = datastore.prepare(formQuery);
            for (Entity formEntity : query.asIterable()) {
                Form form = new Form(formEntity.getProperty("name").toString(), formEntity.getProperty("desc").toString());

                Query fieldQuery = new Query("form_fields");
                fieldQuery.addFilter("user", Query.FilterOperator.EQUAL, user.getUserId());
                fieldQuery.addFilter("form", Query.FilterOperator.EQUAL, form.getName());
                PreparedQuery fieldPQuery = datastore.prepare(fieldQuery);

                Set<FormField> formFields = new HashSet<FormField>();
                for(Entity fieldEntity : fieldPQuery.asIterable()){
                    FormField field = new FormField(fieldEntity.getProperty("name").toString(), fieldEntity.getProperty("type").toString());
                    formFields.add(field);
                }
                form.setFields(formFields);

                formList.add(form);
            }
            return formList;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    public void addListener(FormListener listener) {
        listeners.add(listener);
        if (!formList.isEmpty()) {
            listener.changed();
        }
    }

    public void addForm(Form form) {
        formList.add(form);
        if (!listeners.isEmpty()) {
            for (FormListener listener : listeners) {
                listener.changed();
            }
        }
        storeForm(form);
        updateFormList();
    }

    private void storeForm(Form form){
        Entity formEntity = new Entity("form", form.getName());
        formEntity.setProperty("user", user.getUserId());
        formEntity.setProperty("desc", form.getDescription());
        formEntity.setProperty("name", form.getName());

        DatastoreService datastore = DatastoreServiceFactory.getDatastoreService();
        datastore.put(formEntity);

        for(FormField field : form.getFields()){
            Entity fieldEntity = new Entity("form_fields", field.getName());
            fieldEntity.setProperty("name", field.getName());
            fieldEntity.setProperty("type", field.getType());
            fieldEntity.setProperty("user", user.getUserId());
            fieldEntity.setProperty("form", form.getName());
            datastore.put(fieldEntity);
        }
    }

    public void addData(String name, Map<String, Object> map) {
        Entity formData = new Entity(name + "_data", String.valueOf(System.currentTimeMillis()));
        formData.setProperty("form", name);
        formData.setProperty("user", user.getUserId());

        for(Map.Entry<String, Object> value : map.entrySet()){
            formData.setProperty(value.getKey(), value.getValue());
        }

        DatastoreService dataStore = DatastoreServiceFactory.getDatastoreService();
        dataStore.put(formData);
    }

    public List<Map<String, Object>> getFormData(String name) {
        Query query = new Query(name + "_data");
        query.addFilter("user", Query.FilterOperator.EQUAL, user.getUserId());
        query.addFilter("form", Query.FilterOperator.EQUAL, name);

        DatastoreService dataStore = DatastoreServiceFactory.getDatastoreService();
        PreparedQuery recordList = dataStore.prepare(query);

        List<Map<String, Object>> records = new ArrayList<Map<String, Object>>();
        for(Entity record : recordList.asIterable()){
            Map<String, Object> recordMap = new HashMap<String, Object>();
            recordMap.putAll(record.getProperties());
            recordMap.remove("user");
            recordMap.remove("form");

            records.add(recordMap);
        }

        return records;
    }

    public interface FormListener extends Serializable{
        void changed();
    }
}
