/** calculate totals for the items in the cart */
 public static function calculate_totals()
 {
     // extracted cart totals so that the constructor can call it, rather than
     // this full method. Cart totals are needed for cart widget and themes.
     // Don't want to call shipping api's multiple times per page load
     self::calculate_cart_total();
     // Cart Shipping
     if (self::needs_shipping()) {
         fflcommerce_shipping::calculate_shipping(self::$tax);
     } else {
         fflcommerce_shipping::reset_shipping();
     }
     self::$shipping_total = fflcommerce_shipping::get_total();
     $shipping_method = fflcommerce_shipping::get_chosen_method();
     if (self::get_options()->get('fflcommerce_calc_taxes') == 'yes') {
         self::$tax->calculate_shipping_tax(self::$shipping_total, $shipping_method);
         self::$shipping_tax_total = self::$tax->get_total_shipping_tax_amount();
     }
     // Subtotal
     self::$subtotal_ex_tax = self::$cart_contents_total_ex_tax;
     self::$subtotal = self::$cart_contents_total;
     if (self::get_options()->get('fflcommerce_calc_taxes') == 'yes' && !self::$tax->get_total_shipping_tax_amount()) {
         foreach (self::get_applied_tax_classes() as $tax_class) {
             if (!self::is_not_compounded_tax($tax_class)) {
                 //tax compounded
                 $discount = self::get_options()->get('fflcommerce_tax_after_coupon') == 'yes' ? self::$discount_total : 0;
                 self::$tax->update_tax_amount($tax_class, (self::$subtotal_ex_tax - $discount + self::$tax->get_non_compounded_tax_amount() + self::$shipping_total) * 100);
             }
         }
     }
     self::$total = self::get_cart_subtotal(false) + self::get_cart_shipping_total(false);
     if (self::get_options()->get('fflcommerce_calc_taxes') == 'yes' && self::get_options()->get('fflcommerce_prices_include_tax') == 'no' && self::get_options()->get('fflcommerce_tax_after_coupon') == 'no') {
         self::$total += self::$tax->get_non_compounded_tax_amount() + self::$tax->get_compound_tax_amount();
     }
     // calculate any cart wide discounts from coupons
     $total_product_discounts = self::$discount_total;
     self::$discount_total = $total_cart_discounts = $temp = 0;
     if (self::get_options()->get('fflcommerce_tax_after_coupon') == 'yes') {
         // we need products and shipping with tax out
         $total_cart_discounts = round(self::calculate_cart_discounts_total(self::$cart_contents_total_ex_tax + self::get_cart_shipping_total(false, true)), 2);
         if ($total_cart_discounts > 0) {
             $total_to_use = self::$cart_contents_total_ex_tax + self::$shipping_total;
             if ($total_cart_discounts > $total_to_use) {
                 $total_cart_discounts = $total_to_use - $total_product_discounts;
             }
             $total_tax = self::$tax->get_non_compounded_tax_amount() + self::$tax->get_compound_tax_amount() - self::$tax->get_total_shipping_tax_amount();
             if ($total_tax > 0) {
                 foreach (self::get_applied_tax_classes() as $tax_class) {
                     $rate = self::$tax->get_rate($tax_class);
                     $tax = self::$tax->calc_tax(self::$price_per_tax_class_ex_tax[$tax_class], $rate, false);
                     $discounts = 0.0;
                     $total_tax_part = $tax / $total_tax;
                     // Lower tax by coupon amounts
                     foreach (fflcommerce_cart::get_coupons() as $code) {
                         $coupon = JS_Coupons::get_coupon($code);
                         switch ($coupon['type']) {
                             case 'fixed_cart':
                                 $discounts += self::$tax->calc_tax($coupon['amount'] * $total_tax_part, $rate, false);
                                 break;
                             case 'percent':
                                 $discounts += self::$tax->calc_tax($coupon['amount'] * self::$price_per_tax_class_ex_tax[$tax_class] / ($total_tax_part * 100), $rate, false);
                                 $discounts += $coupon['amount'] * self::$tax->get_shipping_tax($tax_class) / 100;
                                 break;
                         }
                     }
                     $tax -= $discounts;
                     self::$tax->update_tax_amount($tax_class, $tax * 100, false, true);
                 }
             }
             // check again in case tax calcs are disabled
             $total_discounts = $total_cart_discounts + $total_product_discounts;
             if ($total_discounts > $total_to_use) {
                 $total_cart_discounts = $total_to_use - $total_product_discounts;
             }
         }
         foreach (self::get_applied_tax_classes() as $tax_class) {
             $temp += self::$tax->get_tax_amount($tax_class);
         }
         if (self::get_options()->get('fflcommerce_prices_include_tax') == 'no') {
             self::$total += $temp;
         } else {
             self::$total = self::$cart_contents_total_ex_tax + self::$shipping_total + $temp;
         }
     } else {
         //  Taxes are applied before coupons, 'fflcommerce_tax_after_coupon' == 'no'
         if (self::get_options()->get('fflcommerce_prices_include_tax') == 'no') {
             $total_cart_discounts = self::calculate_cart_discounts_total(self::$total);
             if ($total_cart_discounts > self::$total) {
                 $total_cart_discounts = self::$total - $total_product_discounts;
             }
         } else {
             $total_cart_discounts = self::calculate_cart_discounts_total(self::$cart_contents_total_ex_tax + self::$shipping_total);
             if ($total_cart_discounts > 0) {
                 // with an initial discount, recalc taxes and get a proper discount
                 foreach (self::get_applied_tax_classes() as $tax_class) {
                     $rate = self::$tax->get_rate($tax_class);
                     $tax = self::$tax->calc_tax(self::$cart_contents_total_ex_tax, $rate, false);
                     self::$tax->update_tax_amount($tax_class, $tax * 100, false, true);
                     $temp += self::$tax->get_tax_amount($tax_class);
                 }
                 $total_to_use = self::$cart_contents_total_ex_tax + self::$shipping_total + $temp;
                 $total_cart_discounts = self::calculate_cart_discounts_total($total_to_use);
                 if ($total_cart_discounts > $total_to_use) {
                     $total_cart_discounts = $total_to_use - $total_product_discounts;
                 }
             }
         }
     }
     // set the final discount
     self::$discount_total = $total_cart_discounts + $total_product_discounts;
     // adjust the grand total after all discounts
     self::$total -= self::$discount_total;
     if (self::$total < 0) {
         self::$total = 0;
     }
     // with everything calculated, check that coupons depending on cart totals are still valid
     // if they are not, remove them and recursively re-calculate everything all over again.
     $recalc = false;
     if (!empty(self::$applied_coupons)) {
         foreach (self::$applied_coupons as $key => $code) {
             if (!self::is_valid_coupon($code)) {
                 unset(self::$applied_coupons[$key]);
                 fflcommerce_session::instance()->coupons = self::$applied_coupons;
                 $recalc = true;
             }
         }
     }
     if ($recalc) {
         self::calculate_totals();
     }
 }