}
if ($days_running >= 2) {
    echo str_replace("{days}", $days_running, $strPriorityDaysRunning);
    if ($days_running >= 8) {
        echo $strPriorityBasedLastWeek;
    }
    if ($days_running >= 2 && $days_running < 8) {
        echo $strPriorityBasedLastDays;
    }
    if ($days_running == 1) {
        echo $strPriorityBasedYesterday;
    }
} else {
    echo $strPriorityNoData;
}
$banners = phpAds_PriorityPrepareBanners();
$campaigns = phpAds_PriorityPrepareCampaigns();
$profile = array();
list($profile, $profile_correction_executed) = phpAds_PriorityPredictProfile($campaigns, $banners);
$estimated_hits = 0;
for ($p = 0; $p < 24; $p++) {
    $estimated_hits += $profile[$p];
}
if ($campaigns_target) {
    if ($estimated_hits > $campaigns_target) {
        echo $strPriorityEnoughAdViews;
    } else {
        echo $strPriorityNotEnoughAdViews;
    }
} else {
    $campaigns_target = 0;
function phpAds_PriorityCalculate()
{
    global $debug, $debuglog;
    // Prepare information
    $banners = phpAds_PriorityPrepareBanners();
    $campaigns = phpAds_PriorityPrepareCampaigns();
    $profile = array();
    // Determine period
    $maxperiod = 24;
    $period = phpAds_CurrentHour;
    // Populate campaign statistics
    $total_requested = 0;
    $total_campaign_weight = 0;
    $total_targeted_hits = 0;
    $total_other_hits = 0;
    for (reset($campaigns); $c = key($campaigns); next($campaigns)) {
        $targeted_hits = 0;
        $other_hits = 0;
        if ($campaigns[$c]['target'] > 0) {
            for (reset($banners); $b = key($banners); next($banners)) {
                if ($banners[$b]['parent'] == $c) {
                    $targeted_hits += isset($banners[$b]['hits']) ? $banners[$b]['hits'] : 0;
                }
            }
            $total_targeted_hits += $targeted_hits > $campaigns[$c]['target'] ? $campaigns[$c]['target'] : $targeted_hits;
            $total_requested += $campaigns[$c]['target'];
        } else {
            $bannercount = 0;
            for (reset($banners); $b = key($banners); next($banners)) {
                if ($banners[$b]['parent'] == $c) {
                    $other_hits += isset($banners[$b]['hits']) ? $banners[$b]['hits'] : 0;
                    $bannercount++;
                }
            }
            $total_other_hits += $other_hits;
            if ($bannercount > 0) {
                $total_campaign_weight += $campaigns[$c]['weight'];
            }
        }
        $campaigns[$c]['hits'] = $targeted_hits + $other_hits;
    }
    if ($total_requested) {
        // High pri campaigns present, run profiling
        list($profile, $profile_correction_executed) = phpAds_PriorityPredictProfile($campaigns, $banners);
        // Determine estimated number of hits
        $corrected_hits = 0;
        $estimated_hits = 0;
        for ($p = 0; $p < 24; $p++) {
            $corrected_hits += $profile_correction_executed && $p < phpAds_CurrentHour ? $profile[$p] : 0;
            $estimated_hits += $profile[$p];
        }
        // Apply correction to other hits
        if ($profile_correction_executed) {
            // BEGIN REPORTING
            $debuglog .= "\n\n";
            $debuglog .= abs($total_targeted_hits + $total_other_hits - $corrected_hits) . " hits were " . ($total_targeted_hits + $total_other_hits - $corrected_hits > 0 ? "added" : "removed") . " during peak compensation\n";
            // END REPORTING
            $total_other_hits = $corrected_hits - $total_targeted_hits;
        }
        $total_hits = $total_targeted_hits + $total_other_hits;
        $estimated_remaining = $estimated_hits - $total_hits;
        $requested_remaining = $total_requested - $total_targeted_hits;
        if ($estimated_remaining > $requested_remaining) {
            $available_for_targeting = $requested_remaining;
            $available_for_others = $estimated_remaining - $requested_remaining;
        } else {
            $available_for_targeting = $estimated_remaining;
            $available_for_others = 0;
        }
        // BEGIN REPORTING
        $debuglog .= "\n\n";
        $debuglog .= "Estimated number of impressions today: {$estimated_hits} \n";
        $debuglog .= "Estimated number of impressions remaining: {$estimated_remaining} \n";
        $debuglog .= "-----------------------------------------------------\n";
        $debuglog .= "Total number of requested impressions: {$total_requested} \n";
        $debuglog .= "Number of requested impressions satisfied: {$total_targeted_hits} \n";
        $debuglog .= "Number of requested impressions remaining: {$requested_remaining} \n";
        $debuglog .= "-----------------------------------------------------\n\n\n";
        $debuglog .= "Impressions available to meet the targets: {$available_for_targeting} \n";
        $debuglog .= "Impressions left over: {$available_for_others} \n";
        $debuglog .= "-----------------------------------------------------\n";
        // END REPORTING
        $totalassigned = 0;
        for (reset($campaigns); $c = key($campaigns); next($campaigns)) {
            if ($campaigns[$c]['target'] > 0) {
                // BEGIN REPORTING
                $debuglog .= "\n\n\nHIGH-PRI CAMPAIGN {$c} \n";
                $debuglog .= "-----------------------------------------------------\n";
                // END REPORTING
                // Hits assigned  =
                $remaining_for_campaign = $campaigns[$c]['target'] - $campaigns[$c]['hits'];
                $total_profile = 0;
                for ($p = 0; $p < $maxperiod; $p++) {
                    $total_profile += isset($profile[$p]) ? $profile[$p] : 0;
                }
                $profile_uptil_now = 0;
                for ($p = 0; $p < $period; $p++) {
                    $profile_uptil_now += isset($profile[$p]) ? $profile[$p] : 0;
                }
                if ($total_profile == 0) {
                    // No profile available yet, just divide evently
                    $expected_hits_this_period = round($campaigns[$c]['target'] / $maxperiod * ($period + 1));
                } else {
                    if ($profile[$period] == 0) {
                        // Profile available, but no impressions expected this hour
                        // Set the number of expected hits to 1, to make sure the campaign isn't deactivated
                        // and the real impressions won't bring it much of target
                        $expected_hits_this_period = 1;
                    } else {
                        // Profile available, use expected impressions
                        $expected_hits_this_period = round($profile_uptil_now / $total_profile * $campaigns[$c]['target']);
                    }
                }
                // BEGIN REPORTING
                $debuglog .= "Target for campaign: " . $campaigns[$c]['target'] . " \n";
                $debuglog .= "Remaining for campaign: {$remaining_for_campaign} \n";
                // END REPORTING
                if ($period > 0) {
                    // The first time the priority calculation is running there is no
                    // need to compensate, since there are no previous hours available
                    $current_deviance_from_prediction = $campaigns[$c]['hits'] / $expected_hits_this_period;
                    // > 1 = overdelivery, < 1 = underdelivery
                    $expected_today_without_correction = $campaigns[$c]['target'] * $current_deviance_from_prediction;
                    $expected_deviance_todays_in_hits = $expected_today_without_correction - $campaigns[$c]['target'];
                    // BEGIN REPORTING
                    $debuglog .= "Real impressions up till now: " . $campaigns[$c]['hits'] . " \n";
                    $debuglog .= "Expected impressions up till now: {$expected_hits_this_period} \n";
                    $debuglog .= "Deviance from prediction: " . $current_deviance_from_prediction . "x \n";
                    $debuglog .= "Total impressions expected without correction: {$expected_today_without_correction} \n";
                    $debuglog .= "Total deviance expected without correction: {$expected_deviance_todays_in_hits} \n";
                    // END REPORTING
                    $aggression = 2;
                    // The deviance needs to be fixed in the remaining hours / agression
                    $fix_in_no_hours = round(($maxperiod - $period) / $aggression);
                    $extra_to_assign = 0 - $expected_deviance_todays_in_hits / $fix_in_no_hours;
                    // BEGIN REPORTING
                    $debuglog .= "Deviance needs to fixed in: {$fix_in_no_hours} hours (aggression " . $aggression . ")\n";
                    $debuglog .= "Compensate linear by: {$extra_to_assign} \n";
                    // END REPORTING
                    // Find out how many impressions the next hour will generate compared
                    // to the other hours (according to predictions).
                    $total_next_hours = 0;
                    for ($p = $period; $p < $period + $fix_in_no_hours; $p++) {
                        $total_next_hours = isset($profile[$p]) ? $profile[$p] : 0;
                    }
                    $avg_impressions_per_hour = $total_next_hours / $fix_in_no_hours;
                    $compensation_factor = $profile[$period] / $avg_impressions_per_hour;
                    $extra_to_assign = round($compensation_factor * $extra_to_assign);
                    // BEGIN REPORTING
                    $debuglog .= "Average impressions per hour: " . $avg_impressions_per_hour . "\n";
                    $debuglog .= "Expected impressions next hour: " . $profile[$period] . "\n";
                    $debuglog .= "Deviance from average: " . $compensation_factor . "\n";
                    $debuglog .= "Compensate realisticly by: {$extra_to_assign} \n";
                    // END REPORTING
                    $remaining_for_campaign += $extra_to_assign;
                    if ($remaining_for_campaign < 0) {
                        $remaining_for_campaign = 0;
                    }
                }
                // BEGIN REPORTING
                $debuglog .= "Priority for whole campaign: {$remaining_for_campaign} \n";
                // END REPORTING
                $totalassigned += $remaining_for_campaign;
                $total_banner_weight = 0;
                for (reset($banners); $b = key($banners); next($banners)) {
                    if ($banners[$b]['parent'] == $c) {
                        $total_banner_weight += $banners[$b]['weight'];
                    }
                }
                for (reset($banners); $b = key($banners); next($banners)) {
                    if ($banners[$b]['parent'] == $c) {
                        $banners[$b]['priority'] = round($remaining_for_campaign / $total_banner_weight * $banners[$b]['weight']);
                        // BEGIN REPORTING
                        $debuglog .= "- Priority of banner {$b}: " . $banners[$b]['priority'] . " \n";
                        // END REPORTING
                    }
                }
            }
        }
        // BEGIN REPORTING
        $debuglog .= "\n\n\n";
        $debuglog .= "Impressions assigned to meet the targets: {$totalassigned} \n";
        // END REPORTING
        $no_high_pri = !$totalassigned;
    } else {
        // BEGIN REPORTING
        $debuglog .= "-----------------------------------------------------\n";
        $debuglog .= "No targeting needed, skipping profile prediction.\n";
        $debuglog .= "-----------------------------------------------------\n";
        // END REPORTING
        $no_high_pri = true;
    }
    $total_weight = phpAds_PriorityTotalWeight($campaigns, $banners);
    if ($no_high_pri || !$available_for_others) {
        // BEGIN REPORTING
        if ($no_high_pri) {
            $debuglog .= "\n\n\nNo impressions assigned to meet the targets\n";
        } else {
            $debuglog .= "\n\n\nNo or few impressions left over, this would result\n";
            $debuglog .= "in low-priority banners never shown\n";
        }
        $debuglog .= "Total weight: {$total_weight}\n";
        // END REPORTING
        // Use total weight as avaliable impressions for low-pri
        $available_for_others = $total_weight;
        // Boost high-pri banners by total_weight
        $high_pri_boost = $total_weight;
    } else {
        // No boost
        $high_pri_boost = 1;
    }
    // Init array for GCD calculation
    $banner_priorities = array();
    // Flag used when a campaign gets a null priority
    $zero_pri = false;
    // BEGIN REPORTING
    $debuglog .= "Impressions left over: {$available_for_others} \n";
    $debuglog .= "-----------------------------------------------------\n";
    // END REPORTING
    for (reset($campaigns); $c = key($campaigns);) {
        if ($campaigns[$c]['target'] == 0) {
            // BEGIN REPORTING
            $debuglog .= "\n\n\nLOW-PRI CAMPAIGN {$c} \n";
            $debuglog .= "-----------------------------------------------------\n";
            // END REPORTING
            if ($available_for_others > 0) {
                $remaining_for_campaign = round($available_for_others / $total_campaign_weight * $campaigns[$c]['weight']);
            } else {
                $remaining_for_campaign = 0;
            }
            // BEGIN REPORTING
            $debuglog .= "Remaining for campaign: {$remaining_for_campaign} \n";
            // END REPORTING
            $total_banner_weight = 0;
            for (reset($banners); $b = key($banners); next($banners)) {
                if ($banners[$b]['parent'] == $c) {
                    $total_banner_weight += $banners[$b]['weight'];
                }
            }
            for (reset($banners); $b = key($banners); next($banners)) {
                if ($banners[$b]['parent'] == $c) {
                    $banners[$b]['priority'] = round($remaining_for_campaign / $total_banner_weight * $banners[$b]['weight']);
                    if (!$banners[$b]['priority']) {
                        // BEGIN REPORTING
                        $debuglog .= "- Banner {$b} had a null priority.\n";
                        // END REPORTING
                        $zero_pri = true;
                        break;
                    }
                    $banner_priorities[] = $banners[$b]['priority'];
                    // BEGIN REPORTING
                    $debuglog .= "- Assigned priority to banner {$b}: " . $banners[$b]['priority'] . " \n";
                    // END REPORTING
                }
            }
        }
        if ($zero_pri) {
            if (!$available_for_others) {
                // It should never get here, but avoid an endless loop to be safe...
                break;
            }
            // Restart low-pri assignment, increasing available impressions
            $zero_pri = false;
            $banner_priorities = array();
            $available_for_others *= 2;
            $high_pri_boost *= 2;
            // BEGIN REPORTING
            $debuglog .= "\n\n\n-----------------------------------------------------\n";
            $debuglog .= "Restarting...\n";
            $debuglog .= "-----------------------------------------------------\n";
            $debuglog .= "\n\n\nImpressions left over: {$available_for_others} \n";
            $debuglog .= "-----------------------------------------------------\n";
            // END REPORTING
            reset($campaigns);
            continue;
        }
        next($campaigns);
    }
    if ($high_pri_boost > 1 && !$no_high_pri && $total_weight) {
        // We need to raise high-pri priorities to reduce the side-effect
        // introduced increasing remaining impressions for low-pri campaigns
        // BEGIN REPORTING
        $debuglog .= "\n\n\n-----------------------------------------------------\n";
        $debuglog .= "HIGH PRIORITY CAMPAIGNS BOOST ENABLED\n";
        $debuglog .= "-----------------------------------------------------\n";
        // END REPORTING
        // Try to find a GCD to avoid to reduce priority values
        $banner_priorities[] = $high_pri_boost;
        $gcd = phpAds_PriorityGetGCD($banner_priorities);
        if ($gcd > 1) {
            // A GCD was found, we can lower boost rate and low-pri priorities
            $high_pri_boost /= $gcd;
            // BEGIN REPORTING
            $debuglog .= "GCD PRIORITY SOFTENER ENABLED\n";
            $debuglog .= "-----------------------------------------------------\n";
            // END REPORTING
        }
        for (reset($campaigns); $c = key($campaigns); next($campaigns)) {
            if ($campaigns[$c]['target'] > 0) {
                // BEGIN REPORTING
                $debuglog .= "\n\n\nHIGH-PRI CAMPAIGN {$c} \n";
                $debuglog .= "-----------------------------------------------------\n";
                // END REPORTING
                for (reset($banners); $b = key($banners); next($banners)) {
                    if ($banners[$b]['parent'] == $c) {
                        // BEGIN REPORTING
                        $debuglog .= "- Assigned priority to banner {$b}: " . $banners[$b]['priority'] . " * {$high_pri_boost} = ";
                        // END REPORTING
                        $banners[$b]['priority'] *= $high_pri_boost;
                        // BEGIN REPORTING
                        $debuglog .= $banners[$b]['priority'] . "\n";
                        // END REPORTING
                    }
                }
            } elseif ($gcd > 1) {
                // BEGIN REPORTING
                $debuglog .= "\n\n\nLOW-PRI CAMPAIGN {$c} \n";
                $debuglog .= "-----------------------------------------------------\n";
                // END REPORTING
                for (reset($banners); $b = key($banners); next($banners)) {
                    if ($banners[$b]['parent'] == $c) {
                        // BEGIN REPORTING
                        $debuglog .= "- Assigned priority to banner {$b}: " . $banners[$b]['priority'] . " / {$gcd} = ";
                        // END REPORTING
                        $banners[$b]['priority'] /= $gcd;
                        // BEGIN REPORTING
                        $debuglog .= $banners[$b]['priority'] . "\n";
                        // END REPORTING
                    }
                }
            }
        }
    }
    $priority_sum = 0;
    for (reset($banners); $b = current($banners); next($banners)) {
        $priority_sum += $b['priority'];
    }
    if ($priority_sum) {
        $softener = 1;
        while ($priority_sum / $softener > 0x7ffffffe) {
            $softener *= 2;
        }
        if ($softener > 1) {
            $debuglog .= "\n\n\n-----------------------------------------------------\n";
            $debuglog .= "OVERFLOW SOFTENER ENABLED\n";
            $debuglog .= "-----------------------------------------------------\n\n\n\n";
            for (reset($banners); $b = key($banners); next($banners)) {
                // BEGIN REPORTING
                $debuglog .= "- Assigned priority to banner {$b}: " . $banners[$b]['priority'] . " / {$softener} = ";
                // END REPORTING
                $roundto1 = $banners[$b]['priority'] > 0;
                $banners[$b]['priority'] = round($banners[$b]['priority'] / $softener);
                if ($roundto1 && !$banners[$b]['priority']) {
                    $banners[$b]['priority'] = 1;
                    // BEGIN REPORTING
                    $debuglog .= '0, rounding up to ';
                    // END REPORTING
                }
                // BEGIN REPORTING
                $debuglog .= $banners[$b]['priority'] . "\n";
                // END REPORTING
            }
        }
    }
    // Store priority information
    phpAds_PriorityStore($banners, $campaigns);
    return $debuglog;
}