//
//   Copyright 2016  Cityzen Data
//
//   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 io.warp10.script.fwt.wavelets;

import io.warp10.script.fwt.Wavelet;

public class Wavelet_db14 extends Wavelet {

  private static final int transformWavelength = 2;

  private static final double[] scalingDeComposition = new double[] { -1.7871399683109222e-07, 1.7249946753674012e-06, -4.389704901780418e-06, -1.0337209184568496e-05, 6.875504252695734e-05, -4.177724577037067e-05, -0.00038683194731287514, 0.0007080211542354048, 0.001061691085606874, -0.003849638868019787, -0.0007462189892638753, 0.01278949326634007, -0.0056150495303375755, -0.030185351540353976, 0.02698140830794797, 0.05523712625925082, -0.0715489555039835, -0.0867484115681106, 0.13998901658445695, 0.13839521386479153, -0.2180335299932165, -0.27168855227867705, 0.21867068775886594, 0.6311878491047198, 0.5543056179407709, 0.25485026779256437, 0.062364758849384874, 0.0064611534600864905,  };
  private static final double[] waveletDeComposition = new double[] { -0.0064611534600864905, 0.062364758849384874, -0.25485026779256437, 0.5543056179407709, -0.6311878491047198, 0.21867068775886594, 0.27168855227867705, -0.2180335299932165, -0.13839521386479153, 0.13998901658445695, 0.0867484115681106, -0.0715489555039835, -0.05523712625925082, 0.02698140830794797, 0.030185351540353976, -0.0056150495303375755, -0.01278949326634007, -0.0007462189892638753, 0.003849638868019787, 0.001061691085606874, -0.0007080211542354048, -0.00038683194731287514, 4.177724577037067e-05, 6.875504252695734e-05, 1.0337209184568496e-05, -4.389704901780418e-06, -1.7249946753674012e-06, -1.7871399683109222e-07,  };

  private static final double[] scalingReConstruction = new double[] { 0.0064611534600864905, 0.062364758849384874, 0.25485026779256437, 0.5543056179407709, 0.6311878491047198, 0.21867068775886594, -0.27168855227867705, -0.2180335299932165, 0.13839521386479153, 0.13998901658445695, -0.0867484115681106, -0.0715489555039835, 0.05523712625925082, 0.02698140830794797, -0.030185351540353976, -0.0056150495303375755, 0.01278949326634007, -0.0007462189892638753, -0.003849638868019787, 0.001061691085606874, 0.0007080211542354048, -0.00038683194731287514, -4.177724577037067e-05, 6.875504252695734e-05, -1.0337209184568496e-05, -4.389704901780418e-06, 1.7249946753674012e-06, -1.7871399683109222e-07,  };
  private static final double[] waveletReConstruction = new double[] { -1.7871399683109222e-07, -1.7249946753674012e-06, -4.389704901780418e-06, 1.0337209184568496e-05, 6.875504252695734e-05, 4.177724577037067e-05, -0.00038683194731287514, -0.0007080211542354048, 0.001061691085606874, 0.003849638868019787, -0.0007462189892638753, -0.01278949326634007, -0.0056150495303375755, 0.030185351540353976, 0.02698140830794797, -0.05523712625925082, -0.0715489555039835, 0.0867484115681106, 0.13998901658445695, -0.13839521386479153, -0.2180335299932165, 0.27168855227867705, 0.21867068775886594, -0.6311878491047198, 0.5543056179407709, -0.25485026779256437, 0.062364758849384874, -0.0064611534600864905,  };

  static {
    //
    // Reverse the arrays as we do convolutions
    //
    reverse(scalingDeComposition);
    reverse(waveletDeComposition);
  }

  private static final void reverse(double[] array) {
    int i = 0;
    int j = array.length - 1;
    
    while (i < j) {
      double tmp = array[i];
      array[i] = array[j];
      array[j] = tmp;
      i++;
      j--;
    }
  }

  public int getTransformWavelength() {
    return transformWavelength;
  }

  public int getMotherWavelength() {
    return waveletReConstruction.length;
  }

  public double[] getScalingDeComposition() {
    return scalingDeComposition;
  }

  public double[] getWaveletDeComposition() {
    return waveletDeComposition;
  }

  public double[] getScalingReConstruction() {
    return scalingReConstruction;
  }

  public double[] getWaveletReConstruction() {
    return waveletReConstruction;
  }
}

