<commit_before>/*
 * Shredzone Commons - suncalc
 *
 * Copyright (C) 2017 Richard "Shred" Körber
 *   http://commons.shredzone.org
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 */
package org.shredzone.commons.suncalc;

import static org.shredzone.commons.suncalc.util.ExtendedMath.*;

import java.util.Date;

import org.shredzone.commons.suncalc.param.Builder;
import org.shredzone.commons.suncalc.param.LocationParameter;
import org.shredzone.commons.suncalc.param.TimeParameter;
import org.shredzone.commons.suncalc.util.BaseBuilder;
import org.shredzone.commons.suncalc.util.JulianDate;
import org.shredzone.commons.suncalc.util.Moon;
import org.shredzone.commons.suncalc.util.QuadraticInterpolation;
import org.shredzone.commons.suncalc.util.Vector;

/**
 * Calculates the times of the moon.
 */
public final class MoonTimes {

    private final Date rise;
    private final Date set;
    private final boolean alwaysUp;
    private final boolean alwaysDown;

    private MoonTimes(Date rise, Date set, boolean alwaysUp, boolean alwaysDown) {
        this.rise = rise;
        this.set = set;
        this.alwaysUp = alwaysUp;
        this.alwaysDown = alwaysDown;
    }

    /**
     * Starts the computation of {@link MoonTimes}.
     *
     * @return {@link Parameters} to set.
     */
    public static Parameters compute() {
        return new MoonTimesBuilder();
    }

    /**
     * Collects all parameters for {@link MoonTimes}.
     */
    public static interface Parameters extends
            LocationParameter<Parameters>,
            TimeParameter<Parameters>,
            Builder<MoonTimes> {

        /**
         * Checks only the next 24 hours. Rise or set times can be {@code null} if the
         * moon never reaches the point during one day.
         * <p>
         * This is the default.
         *
         * @return itself
         */
        Parameters oneDay();

        /**
         * Computes until rise and set times are found, even if the moon needs more than a
         * day for it. This can increase computation time.
         *
         * @return itself
         */
        Parameters fullCycle();
    }

    /**
     * Builder for {@link MoonTimes}. Performs the computations based on the parameters,
     * and creates a {@link MoonTimes} object that holds the result.
     */
    private static class MoonTimesBuilder extends BaseBuilder<Parameters> implements Parameters {
        private boolean fullCycle = false;
        private double refraction = apparentRefraction(0.0);

        @Override
        public Parameters oneDay() {
            this.fullCycle = false;
            return this;
        }

        @Override
        public Parameters fullCycle() {
            this.fullCycle = true;
            return this;
        }

        @Override
        public MoonTimes execute() {
            JulianDate jd = getJulianDate();

            Double rise = null;
            Double set = null;
            double ye = 0.0;
            boolean alwaysUp = false;
            boolean alwaysDown = false;

            double y_minus = correctedMoonHeight(jd);

            int maxHours = fullCycle ? 365 * 24 : 24;
            for (int hour = 1; hour < maxHours; hour += 2) {
                double y_0 = correctedMoonHeight(jd.atHour(hour));
                double y_plus = correctedMoonHeight(jd.atHour(hour + 1.0));

                QuadraticInterpolation qi = new QuadraticInterpolation(y_minus, y_0, y_plus);
                ye = qi.getYe();

                if (qi.getNumberOfRoots() == 1) {
                    if (y_minus < 0.0) {
                        if (rise == null) {
                            rise = qi.getRoot1() + hour;
                        }
                    } else {
                        if (set == null) {
                            set = qi.getRoot1() + hour;
                        }
                    }
                } else if (qi.getNumberOfRoots() == 2) {
                    if (rise == null) {
                        rise = hour + (ye < 0.0 ? qi.getRoot2() : qi.getRoot1());
                    }
                    if (set == null) {
                        set = hour + (ye < 0.0 ? qi.getRoot1() : qi.getRoot2());
                    }
                }

                if (hour == 23 && rise == null && set == null) {
                    alwaysUp = ye >= 0.0;
                    alwaysDown = ye < 0.0;
                }
<commit_msg>Sonar fix<commit_after>/*
 * Shredzone Commons - suncalc
 *
 * Copyright (C) 2017 Richard "Shred" Körber
 *   http://commons.shredzone.org
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 */
package org.shredzone.commons.suncalc;

import static org.shredzone.commons.suncalc.util.ExtendedMath.*;

import java.util.Date;

import org.shredzone.commons.suncalc.param.Builder;
import org.shredzone.commons.suncalc.param.LocationParameter;
import org.shredzone.commons.suncalc.param.TimeParameter;
import org.shredzone.commons.suncalc.util.BaseBuilder;
import org.shredzone.commons.suncalc.util.JulianDate;
import org.shredzone.commons.suncalc.util.Moon;
import org.shredzone.commons.suncalc.util.QuadraticInterpolation;
import org.shredzone.commons.suncalc.util.Vector;

/**
 * Calculates the times of the moon.
 */
public final class MoonTimes {

    private final Date rise;
    private final Date set;
    private final boolean alwaysUp;
    private final boolean alwaysDown;

    private MoonTimes(Date rise, Date set, boolean alwaysUp, boolean alwaysDown) {
        this.rise = rise;
        this.set = set;
        this.alwaysUp = alwaysUp;
        this.alwaysDown = alwaysDown;
    }

    /**
     * Starts the computation of {@link MoonTimes}.
     *
     * @return {@link Parameters} to set.
     */
    public static Parameters compute() {
        return new MoonTimesBuilder();
    }

    /**
     * Collects all parameters for {@link MoonTimes}.
     */
    public static interface Parameters extends
            LocationParameter<Parameters>,
            TimeParameter<Parameters>,
            Builder<MoonTimes> {

        /**
         * Checks only the next 24 hours. Rise or set times can be {@code null} if the
         * moon never reaches the point during one day.
         * <p>
         * This is the default.
         *
         * @return itself
         */
        Parameters oneDay();

        /**
         * Computes until rise and set times are found, even if the moon needs more than a
         * day for it. This can increase computation time.
         *
         * @return itself
         */
        Parameters fullCycle();
    }

    /**
     * Builder for {@link MoonTimes}. Performs the computations based on the parameters,
     * and creates a {@link MoonTimes} object that holds the result.
     */
    private static class MoonTimesBuilder extends BaseBuilder<Parameters> implements Parameters {
        private boolean fullCycle = false;
        private double refraction = apparentRefraction(0.0);

        @Override
        public Parameters oneDay() {
            this.fullCycle = false;
            return this;
        }

        @Override
        public Parameters fullCycle() {
            this.fullCycle = true;
            return this;
        }

        @Override
        public MoonTimes execute() {
            JulianDate jd = getJulianDate();

            Double rise = null;
            Double set = null;
            boolean alwaysUp = false;
            boolean alwaysDown = false;

            double y_minus = correctedMoonHeight(jd);

            int maxHours = fullCycle ? 365 * 24 : 24;
            for (int hour = 1; hour < maxHours; hour += 2) {
                double y_0 = correctedMoonHeight(jd.atHour(hour));
                double y_plus = correctedMoonHeight(jd.atHour(hour + 1.0));

                QuadraticInterpolation qi = new QuadraticInterpolation(y_minus, y_0, y_plus);
                double ye = qi.getYe();

                if (qi.getNumberOfRoots() == 1) {
                    if (y_minus < 0.0) {
                        if (rise == null) {
                            rise = qi.getRoot1() + hour;
                        }
                    } else {
                        if (set == null) {
                            set = qi.getRoot1() + hour;
                        }
                    }
                } else if (qi.getNumberOfRoots() == 2) {
                    if (rise == null) {
                        rise = hour + (ye < 0.0 ? qi.getRoot2() : qi.getRoot1());
                    }
                    if (set == null) {
                        set = hour + (ye < 0.0 ? qi.getRoot1() : qi.getRoot2());
                    }
                }

                if (hour == 23 && rise == null && set == null) {
                    alwaysUp = ye >= 0.0;
                    alwaysDown = ye < 0.0;
                }

{'fraction_non_alphanumeric': 0.09308510638297872, 'fraction_numerical': 0.009361702127659575, 'mean_word_length': 1.7217718587145339, 'pattern_counts': {'":': 0, '<': 23, '<?xml version=': 0, '>': 15, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6343522', 'n_tokens_mistral': 2611, 'n_tokens_neox': 2468, 'n_words': 761}