/*
 * Copyright (c) 2018, Linz Center of Mechatronics GmbH (LCM), web: www.lcm.at
 * All rights reserved.
 */
/*
 * This file is licensed according to the BSD 3-clause license as follows:
 * 
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *     * Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above copyright
 *       notice, this list of conditions and the following disclaimer in the
 *       documentation and/or other materials provided with the distribution.
 *     * Neither the name of the "Linz Center of Mechatronics GmbH" and "LCM" nor
 *       the names of its contributors may be used to endorse or promote products
 *       derived from this software without specific prior written permission.
 * 
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL "Linz Center of Mechatronics GmbH" BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
/*
 * This file is part of X2C. web: x2c.lcm.at
 * $LastChangedRevision: 3474 $
 * $LastChangedDate:: 2024-11-06 18:00:53 +0100#$
 */
// USERCODE-BEGIN:Description                                                                                           
/* Description: */
// USERCODE-END:Description                                                                                             

package at.lcm.x2c.library.filter;

import at.lcm.x2c.core.structure.*;
import at.lcm.bu21.general.dtypes.*;

// USERCODE-BEGIN:Imports                                                                                               
// USERCODE-END:Imports                                                                                                 

@SuppressWarnings("unused")
public class ConvFnc_IIR_Float64 extends JavaConversionFunction {
    private static final long serialVersionUID = 1L;

    @Override
    public void convertMaskToImplementation() throws Exception {

        // Mask Parameter: CoeffB                                                                                       
        MaskDouble CoeffBMaskVal = 
            (MaskDouble)this.getMaskParameter("CoeffB").getMaskDataType();
        TNumeric CoeffBMaskData = 
            (TNumeric)CoeffBMaskVal.getData();
        // Mask Parameter: CoeffA                                                                                       
        MaskDouble CoeffAMaskVal = 
            (MaskDouble)this.getMaskParameter("CoeffA").getMaskDataType();
        TNumeric CoeffAMaskData = 
            (TNumeric)CoeffAMaskVal.getData();
        // Mask Parameter: ts_fact                                                                                      
        MaskDouble ts_factMaskVal = 
            (MaskDouble)this.getMaskParameter("ts_fact").getMaskDataType();
        TNumeric ts_factMaskData = 
            (TNumeric)ts_factMaskVal.getData();

        // Implementation Parameter: coeffB                                                                             
        TNumeric coeffBCtrVal = this.getImplementationParameterData("coeffB");
        // Implementation Parameter: coeffA                                                                             
        TNumeric coeffACtrVal = this.getImplementationParameterData("coeffA");
        // Implementation Parameter: inputBuffer                                                                        
        TNumeric inputBufferCtrVal = this.getImplementationParameterData("inputBuffer");
        // Implementation Parameter: outputBuffer                                                                       
        TNumeric outputBufferCtrVal = this.getImplementationParameterData("outputBuffer");
        // Implementation Parameter: indexIn                                                                            
        TNumeric indexInCtrVal = this.getImplementationParameterData("indexIn");
        // Implementation Parameter: indexOut                                                                           
        TNumeric indexOutCtrVal = this.getImplementationParameterData("indexOut");
        // Implementation Parameter: orderN                                                                             
        TNumeric orderNCtrVal = this.getImplementationParameterData("orderN");
        // Implementation Parameter: orderD                                                                             
        TNumeric orderDCtrVal = this.getImplementationParameterData("orderD");

// USERCODE-BEGIN:ConvMaskToImplementation                                                                              
        final int SIZE_COL = 32; /* maximum order */
        final int SIZE_ROW = 1;

        /* get order of numerator and denominator */
        int orderN = CoeffBMaskData.getNumColumns();
        int orderD = CoeffAMaskData.getNumColumns();

        /* check numerator input for correct size */
        if ((orderN > SIZE_COL) || (CoeffBMaskData.getNumRows() != SIZE_ROW)) {
            throw new Exception("Numerator size mismatch in column: expected=(" + SIZE_ROW + ", " + SIZE_COL + ") "
                    + "got=(" + CoeffBMaskData.getNumRows() + "," + orderN + ")");
        }
        /* check denominator input for correct size */
        if ((orderD > SIZE_COL) || (CoeffAMaskData.getNumRows() != SIZE_ROW)) {
            throw new Exception("Numerator size mismatch in column: expected=(" + SIZE_ROW + ", " + SIZE_COL + ") "
                    + "got=(" + CoeffAMaskData.getNumRows() + "," + orderD + ")");
        }
        /* check relation of order number between numerator and denominator */
        if (orderN > orderD) {
            throw new Exception("Order of numerator must not be higher than order of denominator!");
        }

        /* get coefficient a0 for normalization purposes */
        double a0 = CoeffAMaskData.getReal(0, 0);
        if (a0 == 0) {
            throw new Exception("Coefficient a0 must not be zero!");
        }

        /* get numerator coefficients */
        Double[] coeffB = new Double[SIZE_COL];
        for (int i = 0; i < orderN; i++) {
            coeffB[i] = CoeffBMaskData.getReal(0, orderN - i - 1); /* read coefficients in reversed order */
            coeffB[i] = coeffB[i] / a0; /* normalization */
        }
        for (int i = orderN; i < SIZE_COL; i++) {
            coeffB[i] = 0.0;
        }

        /* get denominator coefficients */
        Double[] coeffA = new Double[SIZE_COL - 1];
        for (int i = 0; i < (orderD - 1); i++) {
            coeffA[i] = CoeffAMaskData.getReal(0, orderD - i - 1); /* read coefficients in reversed order and omit a0 */
            coeffA[i] = coeffA[i] / a0; /* normalization */
        }
        for (int i = orderD - 1; i < (SIZE_COL - 1); i++) {
            coeffA[i] = 0.0;
        }

        /* set implementation parameter values */
        coeffBCtrVal = new TNumeric(coeffB);
        coeffACtrVal = new TNumeric(coeffA);
        orderNCtrVal.setReal(0, 0, orderN);
        orderDCtrVal.setReal(0, 0,
                orderD - 1); /* due to normalization a0 is always 1 and hence doesn't have to be transfered */

// USERCODE-END:ConvMaskToImplementation                                                                                
        this.setImplementationParameterData("coeffB", coeffBCtrVal);
        this.setImplementationParameterData("coeffA", coeffACtrVal);
        this.setImplementationParameterData("inputBuffer", inputBufferCtrVal);
        this.setImplementationParameterData("outputBuffer", outputBufferCtrVal);
        this.setImplementationParameterData("indexIn", indexInCtrVal);
        this.setImplementationParameterData("indexOut", indexOutCtrVal);
        this.setImplementationParameterData("orderN", orderNCtrVal);
        this.setImplementationParameterData("orderD", orderDCtrVal);
    }

    @Override
    public void convertImplementationToMask() throws Exception {

        // Mask Parameter: CoeffB                                                                                       
        MaskDouble CoeffBMaskVal = 
            (MaskDouble)this.getMaskParameter("CoeffB").getMaskDataType();
        TNumeric CoeffBMaskData = 
            (TNumeric)CoeffBMaskVal.getData();
        // Mask Parameter: CoeffA                                                                                       
        MaskDouble CoeffAMaskVal = 
            (MaskDouble)this.getMaskParameter("CoeffA").getMaskDataType();
        TNumeric CoeffAMaskData = 
            (TNumeric)CoeffAMaskVal.getData();
        // Mask Parameter: ts_fact                                                                                      
        MaskDouble ts_factMaskVal = 
            (MaskDouble)this.getMaskParameter("ts_fact").getMaskDataType();
        TNumeric ts_factMaskData = 
            (TNumeric)ts_factMaskVal.getData();

        // Implementation Parameter: coeffB                                                                             
        TNumeric coeffBCtrVal = this.getImplementationParameterData("coeffB");
        // Implementation Parameter: coeffA                                                                             
        TNumeric coeffACtrVal = this.getImplementationParameterData("coeffA");
        // Implementation Parameter: inputBuffer                                                                        
        TNumeric inputBufferCtrVal = this.getImplementationParameterData("inputBuffer");
        // Implementation Parameter: outputBuffer                                                                       
        TNumeric outputBufferCtrVal = this.getImplementationParameterData("outputBuffer");
        // Implementation Parameter: indexIn                                                                            
        TNumeric indexInCtrVal = this.getImplementationParameterData("indexIn");
        // Implementation Parameter: indexOut                                                                           
        TNumeric indexOutCtrVal = this.getImplementationParameterData("indexOut");
        // Implementation Parameter: orderN                                                                             
        TNumeric orderNCtrVal = this.getImplementationParameterData("orderN");
        // Implementation Parameter: orderD                                                                             
        TNumeric orderDCtrVal = this.getImplementationParameterData("orderD");

// USERCODE-BEGIN:ConvImplementationToMask                                                                              
        if (true) {
            throw new Exception(
                    "Implementation-to-Mask conversion not implemented for Block 'IIR', Implementation 'Float64' in Library 'Filter' due to ambiguous parameters");
        }
// USERCODE-END:ConvImplementationToMask                                                                                
        this.getMaskParameter("CoeffB").setValue(CoeffBMaskData.toFullString());
        this.getMaskParameter("CoeffA").setValue(CoeffAMaskData.toFullString());
        this.getMaskParameter("ts_fact").setValue(ts_factMaskData.toFullString());
    }
}
