/*
* LaGUI: A graphical application framework.
* Copyright (C) 2022-2023 Wu Yiming
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* 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.  See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

#include "la_5.h"

#include "la_tns.h"

#include "la_util.h"
#include <math.h>

extern tnsMain *T;

//z3 = 1/( linearintp(1/z1),(1/z2),t )
//L,R is GLocation
void tnsInterpolatePerspective4dv(tnsVector4d LG, tnsVector4d RG, tnsVector4d L, tnsVector4d R, real T, tnsVector3d Result){
    ////real t = (w - L[3]) / (R[3] - L[3]);
    real z = 1 / tnsLinearItp(1 / L[2], 1 / R[2], T);

    ////Result[2] = tnsLinearItp(L[2] / L[3], R[2] / R[3], t)*w;
    ////Result[0] = tnsLinearItp(L[0] / L[3], R[0] / R[3], t)*w;
    ////Result[1] = tnsLinearItp(L[1] / L[3], R[1] / R[3], t)*w;

    Result[0] = tnsLinearItp(L[0] / L[2], R[0] / R[2], T) * z;
    Result[1] = tnsLinearItp(L[1] / L[2], R[1] / R[2], T) * z;
    Result[2] = z;

    //real x1z1 = LG[0] / LG[2], x2z2 = RG[0] / RG[2];
    //real x3 = tnsLinearItp(LG[0], RG[0], T);
    //real z3 = tnsLinearItp(LG[2], RG[2], T);
    //real t = (x3 / z3 - x1z1) / (x2z2 - x1z1);
    //Result[0] = tnsLinearItp(L[0], R[0], t);
    //Result[1] = tnsLinearItp(L[1], R[1], t);
    //Result[2] = tnsLinearItp(L[2], R[2], t);
}

tnsLineStrip *tnsCreateLineStrip(){
    tnsLineStrip *ls = CreateNew(tnsLineStrip);
    return ls;
}
tnsLineStripPoint *tnsAppendPoint(tnsLineStrip *ls, real X, real Y, real Z){
    tnsLineStripPoint *lsp = CreateNew(tnsLineStripPoint);

    lsp->P[0] = X;
    lsp->P[1] = Y;
    lsp->P[2] = Z;

    lstAppendItem(&ls->Points, lsp);

    ls->PointCount++;

    return lsp;
}
tnsLineStripPoint *tnsPushPoint(tnsLineStrip *ls, real X, real Y, real Z){
    tnsLineStripPoint *lsp = CreateNew(tnsLineStripPoint);

    lsp->P[0] = X;
    lsp->P[1] = Y;
    lsp->P[2] = Z;

    lstPushItem(&ls->Points, lsp);

    ls->PointCount++;

    return lsp;
}

void tnsRemovePoint(tnsLineStrip *ls, tnsLineStripPoint *lsp){
    lstRemoveItem(&ls->Points, lsp);
    FreeMem(lsp);
}

void tnsDestroyLineStrip(tnsLineStrip *ls){
    tnsLineStripPoint *lsp;
    while (lsp = lstPopItem(&ls->Points)){
        FreeMem(lsp);
    }
    FreeMem(ls);
}