/*
 * Copyright 2012 s_wolff.
 *
 * Licensed 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.aegee.runanddine.feedback;

import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;

import org.aegee.runanddine.BasePage;
import org.aegee.runanddine.pathfinder.OptGroup;
import org.aegee.runanddine.runanddine.RDManager;
import org.aegee.runanddine.runanddine.RunAndDine;
import org.aegee.runanddine.util.DateFormat;
import org.aegee.runanddine.util.data.ModelNotExistingException;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.repeater.RepeatingView;
import org.apache.wicket.request.http.flow.AbortWithHttpErrorCodeException;
import org.apache.wicket.request.mapper.parameter.PageParameters;

/**
 * Displays summarized and detailed feedback results
 * @author s_wolff
 */
public class FeedbackInspector extends BasePage {

    /**
     * Page constructor for page parameters
     * @param parameters HTTP parameters
     */
    public FeedbackInspector(PageParameters parameters) {
        this(parameters, parameters.get("id").toInt());
    }

    /**
     * Page constructor for RunAndDine ID
     * @param id ID of RunAndDine to show feedback results from
     * @throws ModelNotExistingException Gets thrown if there is no RunAndDine for given ID
     */
    public FeedbackInspector(int id) throws ModelNotExistingException {
        this(null, id);
    }

    /**
     * Page constructor for RunAndDine
     * @param event RunAndDine to show feedback results from
     */
    public FeedbackInspector(RunAndDine event) {
        this(null, event.getId());
    }

    /**
     * Page constructor for page parameters and ID of RunAndDine
     * @param parameters HTTP parameters
     * @param providedId ID of RunAndDine to show feedback results from
     */
    public FeedbackInspector(PageParameters parameters, final int providedId) {
        super(parameters);
        
        try{
            RunAndDine.OBJECTS.getById(providedId);
        }catch(ModelNotExistingException e){
            // assure that the given id is valid -> do not need to care for some NullPointer possibilities
            throw new AbortWithHttpErrorCodeException(404, "The specified Run&Dine is not available.");
        }

        Calendar cal = new GregorianCalendar();
        try {
            cal.setTime(RDManager.getInstance().getById(providedId).getDate());
        } catch (ModelNotExistingException ex) {
            Logger.getLogger(FeedbackInspector.class.getName()).log(Level.SEVERE, null, ex);
        }

        // set the feedback Deadline 1 Month after the Run&Dine         
        cal.add(Calendar.MONTH, 1);
        Date feedbackDeadline = cal.getTime();

        String dateOfRaD = "";
        try {
            dateOfRaD = DateFormat.format(RDManager.getInstance().getById(providedId).getDate());
        } catch (ModelNotExistingException ex) {
            Logger.getLogger(FeedbackInspector.class.getName()).log(Level.SEVERE, null, ex);
        }
        String deadline = feedbackDeadline.toString();
        this.add(new Label("date", dateOfRaD));
        this.add(new Label("deadline", deadline));

        float pointsRaD = 0;
        int minRaD = 10;
        int maxRaD = 0;
        float pointsMotto = 0;
        int minMotto = 10;
        int maxMotto = 0;

        RepeatingView otherRepeater = new RepeatingView("others");
        this.add(otherRepeater);
        RepeatingView otherWishRepeater = new RepeatingView("othersWished");
        this.add(otherWishRepeater);
        RepeatingView additionalFeedbackRepeater = new RepeatingView("answer");
        this.add(additionalFeedbackRepeater);

        //Counters for all the bools
        int counterMail = 0;
        int counterCanteen = 0;
        int counterFacebook = 0;
        int counterFriends = 0;
        int counterMailWish = 0;
        int counterCanteenWish = 0;
        int counterFacebookWish = 0;
        int counterFriendsWish = 0;

        // Here we will get the data from DB
        List<Feedback> myFeedbackList = FeedbackManager.getInstance().getAllByRunAndDineId(providedId);

        this.add(new Label("numFeedback", myFeedbackList.size() + ""));
        this.add(new Label("numParticipants", OptGroup.OBJECTS.getAllByRunAndDineId(providedId).size()*2 + ""));

        int listSize = myFeedbackList.size();
        for (Feedback feedback : myFeedbackList) {

            // First we get the values from the 0 till 10 scale
            int actualRaDPoints = feedback.getPointsRaD();
            pointsRaD += actualRaDPoints;

            int actualMottoPoints = feedback.getPointsMotto();
            pointsMotto += actualMottoPoints;

            //proof for new min for Run and Dine
            if (actualRaDPoints < minRaD) {
                minRaD = actualRaDPoints;
            }

            //proof for new max for Run and Dine
            if (actualRaDPoints > maxRaD) {
                maxRaD = actualRaDPoints;
            }

            //proof for new min for motto
            if (actualMottoPoints < minMotto) {
                minMotto = actualMottoPoints;
            }

            //proof for new max for motto
            if (actualMottoPoints > maxMotto) {
                maxMotto = actualMottoPoints;
            }

            // Lets get the textual answers and save them in 
            if (feedback.getAdditionalFeedback() != null) {
                additionalFeedbackRepeater.add(new Label(additionalFeedbackRepeater.newChildId(), feedback.getAdditionalFeedback().trim()));
            }

            // Now count how often each of this whole bools are true
            if (feedback.getAdvMail()) {
                counterMail++;
            }
            if (feedback.getAdvCanteen()) {
                counterCanteen++;
            }
            if (feedback.getAdvFacebook()) {
                counterFacebook++;
            }
            if (feedback.getAdvFriends()) {
                counterFriends++;
            }
            if (feedback.getAdvMailWish()) {
                counterMailWish++;
            }
            if (feedback.getAdvCanteenWish()) {
                counterCanteenWish++;
            }
            if (feedback.getAdvFacebookWish()) {
                counterFacebookWish++;
            }
            if (feedback.getAdvFriendsWish()) {
                counterFriendsWish++;
            }

            // Lets get the textual answers of the advertisement media
            if (feedback.getOtherAdv() != null) {
                otherRepeater.add(new Label(otherRepeater.newChildId(), feedback.getOtherAdv().trim()));
            }
            if (feedback.getOtherWish() != null) {
                otherWishRepeater.add(new Label(otherWishRepeater.newChildId(), feedback.getOtherWish().trim()));
            }
        }

        if (listSize == 0) {
            // TODO: dont know what this shit is -- just trying to make it run
            listSize++;
        }

        //A float to round to second decimal place
        float rounder = 100;
        float avRaD;
        float avMotto;
        if (listSize > 0) {
            avRaD = pointsRaD / listSize;
            avRaD = Math.round(avRaD * rounder) / rounder;
            avMotto = pointsMotto / listSize;
            avMotto = Math.round(avMotto * rounder) / rounder;
        } else {
            avRaD = 0;
            avMotto = 0;
        }

        this.add(new Label("averageRaD", String.valueOf(avRaD)));
        this.add(new Label("minRaD", String.valueOf(minRaD)));
        this.add(new Label("maxRaD", String.valueOf(maxRaD)));
        this.add(new Label("averageMotto", String.valueOf(avMotto)));
        this.add(new Label("minMotto", String.valueOf(minMotto)));
        this.add(new Label("maxMotto", String.valueOf(maxMotto)));

        //calculation of percentage choose of the bools
        int percMail, percFb, percCanteen, percFriends, percMailWish, percFbWish, percCanteenWish, percFriendsWish;
        if (listSize > 0) {
            percMail = counterMail * 100 / listSize;
            percFb = counterFacebook * 100 / listSize;
            percCanteen = counterCanteen * 100 / listSize;
            percFriends = counterFriends * 100 / listSize;
            percMailWish = counterMailWish * 100 / listSize;
            percFbWish = counterFacebookWish * 100 / listSize;
            percCanteenWish = counterCanteenWish * 100 / listSize;
            percFriendsWish = counterFriendsWish * 100 / listSize;
        } else {
            percMail = 0;
            percFb = 0;
            percCanteen = 0;
            percFriends = 0;
            percMailWish = 0;
            percFbWish = 0;
            percCanteenWish = 0;
            percFriendsWish = 0;
        }

        this.add(new Label("mail", String.valueOf(percMail) + " %"));
        this.add(new Label("facebook", String.valueOf(percFb) + " %"));
        this.add(new Label("canteen", String.valueOf(percCanteen) + " %"));
        this.add(new Label("friends", String.valueOf(percFriends) + " %"));
        this.add(new Label("mailWish", String.valueOf(percMailWish) + " %"));
        this.add(new Label("facebookWish", String.valueOf(percFbWish) + " %"));
        this.add(new Label("canteenWish", String.valueOf(percCanteenWish) + " %"));
        this.add(new Label("friendsWish", String.valueOf(percFriendsWish) + " %"));
    }
}