import { Feature } from 'geojson';
import { FeatureCollection } from 'geojson';
import { Point } from 'geojson';
import { Polygon } from 'geojson';
import { Position } from 'geojson';

/**
 * 変換の方向を示す型定義
 * - forw: 順方向（ソース → ターゲット）
 * - bakw: 逆方向（ターゲット → ソース）
 */
export declare type BiDirectionKey = "forw" | "bakw";

export declare type Centroid = Feature<Point>;

export declare type CentroidBD = {
    [key in BiDirectionKey]?: Centroid;
};

/**
 * コンパイルされた設定の型定義
 * 変換に必要な全ての情報を含む
 */
export declare interface Compiled {
    version?: number;
    points: PointSet[];
    tins_points: (number | string)[][][];
    weight_buffer: WeightBufferBD;
    strict_status?: StrictStatus;
    centroid_point: Position[];
    edgeNodes?: PointSet[];
    kinks_points?: Position[];
    yaxisMode?: YaxisMode;
    vertexMode?: VertexMode;
    strictMode?: StrictMode;
    vertices_params: number[][];
    vertices_points: PointSet[];
    edges: EdgeSet[];
    bounds?: number[][];
    boundsPolygon?: Feature<Polygon>;
    wh?: number[];
    xy?: number[];
}

export declare interface CompiledLegacy extends Compiled {
    tins?: TinsBD;
    centroid?: CentroidBD;
    kinks?: KinksBD;
    vertices_params: number[][] & VerticesParamsBD;
    edges: EdgeSet[] & EdgeSetLegacy[];
}

/**
 * 三角形の頂点の座標系を反転する
 * @param tri 元の三角形
 * @returns 座標系が反転された三角形
 */
export declare function counterTri(tri: Tri): Tri;

/**
 * エッジの終点を表す型
 * [始点のインデックス, 終点のインデックス]
 */
export declare type Edge = [number, number];

/**
 * エッジセットの型
 * [始点と終点の間の中間点群（地図座標系）,
 *  始点と終点の間の中間点群（変換先座標系）,
 *  始点と終点のインデックスペア]
 */
export declare type EdgeSet = [Position[], Position[], Edge];

/**
 * 古いバージョンのエッジセット型
 * @deprecated 2.00703以降は EdgeSet を使用
 */
export declare type EdgeSetLegacy = {
    illstNodes: Position[];
    mercNodes: Position[];
    startEnd: Edge;
};

export declare const format_version = 2.00703;

declare interface IndexedTins {
    gridNum: number;
    xOrigin: number;
    yOrigin: number;
    xUnit: number;
    yUnit: number;
    gridCache: number[][][];
}

export declare type IndexedTinsBD = {
    [key in BiDirectionKey]?: IndexedTins;
};

export declare type Kinks = FeatureCollection<Point>;

export declare type KinksBD = {
    [key in BiDirectionKey]?: Kinks;
};

/**
 * エッジセットを正規化する
 * 古いバージョンのフォーマットを新しいフォーマットに変換する
 *
 * @param edges エッジセット配列
 * @param version バージョン番号（オプション）
 * @returns 正規化されたエッジセット配列
 */
export declare function normalizeEdges(edges: EdgeSet[] | EdgeSetLegacy[], version?: number): EdgeSet[];

/**
 * 座標ペアの型定義。[ソース座標, ターゲット座標] の形式
 */
export declare type PointSet = [Position, Position];

declare type PropertiesTri = {
    [key in PropertyTriKey]: PropertyTri;
};

declare type PropertyTri = {
    geom: Position;
    index: number | string;
};

export declare type PropertyTriKey = "a" | "b" | "c";

/**
 * 三角形の頂点の順序を修正する
 * 地図外郭の頂点を含む三角形について、頂点の順序を統一する
 * @param tins 三角形群
 * @returns 頂点順序が修正された三角形群
 */
export declare function rotateVerticesTriangle(tins: Tins): Tins;

/**
 * 厳密性モードの型定義
 * - strict: 厳密モード（交差なしを保証）
 * - auto: 自動モード（可能な限り厳密に）
 * - loose: 緩和モード（交差を許容）
 */
export declare type StrictMode = "strict" | "auto" | "loose";

/**
 * 厳密性モードの生成結果
 * - strict: 厳密モード生成成功
 * - auto: 厳密モードでエラー
 * - loose: 緩和モード
 */
export declare type StrictStatus = "strict" | "strict_error" | "loose";

export declare type Tins = FeatureCollection<Polygon, PropertiesTri>;

export declare type TinsBD = {
    [key in BiDirectionKey]?: Tins;
};

/**
 * 座標変換の基本機能を提供するクラス
 *
 * 2つの座標系間の変換を、TINネットワークを使用して実現します。
 * このクラスは基本的な変換機能のみを提供し、
 * 設定ファイルの生成などの追加機能はTinクラスで提供されます。
 */
export declare class Transform {
    /**
     * 各種モードの定数定義
     * すべてreadonlyで、型安全性を確保
     */
    static VERTEX_PLAIN: "plain";
    static VERTEX_BIRDEYE: "birdeye";
    static MODE_STRICT: "strict";
    static MODE_AUTO: "auto";
    static MODE_LOOSE: "loose";
    static STATUS_STRICT: "strict";
    static STATUS_ERROR: "strict_error";
    static STATUS_LOOSE: "loose";
    static YAXIS_FOLLOW: "follow";
    static YAXIS_INVERT: "invert";
    points: PointSet[];
    pointsWeightBuffer?: WeightBufferBD;
    strict_status?: StrictStatus;
    vertices_params?: VerticesParamsBD;
    centroid?: CentroidBD;
    edgeNodes?: PointSet[];
    edges?: EdgeSet[];
    tins?: TinsBD;
    kinks?: KinksBD;
    yaxisMode: YaxisMode;
    strictMode: StrictMode;
    vertexMode?: VertexMode;
    bounds?: number[][];
    boundsPolygon?: Feature<Polygon>;
    wh?: number[];
    xy?: number[];
    indexedTins?: IndexedTinsBD;
    stateFull: boolean;
    stateTriangle?: Tri;
    stateBackward?: boolean;
    constructor();
    /**
     * コンパイルされた設定を適用します
     *
     * @param compiled - コンパイルされた設定オブジェクト
     * @returns 変換に必要な主要なオブジェクトのセット
     *
     * 以下の処理を行います：
     * 1. バージョンに応じた設定の解釈
     * 2. 各種パラメータの復元
     * 3. TINネットワークの再構築
     * 4. インデックスの作成
     */
    setCompiled(compiled: Compiled | CompiledLegacy): void;
    /**
     * TINネットワークのインデックスを作成します
     *
     * インデックスは変換処理を高速化するために使用されます。
     * グリッド形式のインデックスを作成し、各グリッドに
     * 含まれる三角形を記録します。
     */
    addIndexedTin(): void;
    /**
     * 座標変換を実行します
     *
     * @param apoint - 変換する座標
     * @param backward - 逆方向の変換かどうか
     * @param ignoreBounds - 境界チェックを無視するかどうか
     * @returns 変換後の座標、または境界外の場合はfalse
     *
     * @throws {Error} 逆方向変換が許可されていない状態での逆変換時
     */
    transform(apoint: number[], backward?: boolean, ignoreBounds?: boolean): number[] | false;
}

/**
 * 点の座標を変換する
 * 点が三角形の内部にある場合は三角形による変換を、
 * 外部にある場合は頂点パラメータによる変換を行う
 * @param point 変換する点
 * @param tins 三角形群
 * @param indexedTins インデックス付き三角形群（オプション）
 * @param verticesParams 頂点パラメータ（オプション）
 * @param centroid 重心点（オプション）
 * @param weightBuffer 重み付けバッファ（オプション）
 * @param stateTriangle 状態三角形（オプション）
 * @param stateSetFunc 状態設定関数（オプション）
 * @returns 変換後の座標
 */
export declare function transformArr(point: Feature<Point>, tins: Tins, indexedTins?: IndexedTins, verticesParams?: VerticesParams, centroid?: Feature<Point>, weightBuffer?: WeightBuffer, stateTriangle?: Tri, stateSetFunc?: (tri?: Tri) => void): Position;

export declare type Tri = Feature<Polygon, PropertiesTri>;

/**
 * 頂点モードの型定義
 * - plain: 通常モード
 * - birdeye: 鳥瞰図モード
 */
export declare type VertexMode = "plain" | "birdeye";

declare type VerticesParams = [number[], Tins[]?];

export declare type VerticesParamsBD = {
    [key in BiDirectionKey]?: VerticesParams;
};

declare type WeightBuffer = {
    [index: string]: number;
};

/**
 * 両方向の重み付けバッファの型定義
 */
export declare type WeightBufferBD = {
    [key in BiDirectionKey]?: WeightBuffer;
};

/**
 * Y軸の向きの型定義
 * - follow: Y軸の向きを維持
 * - invert: Y軸の向きを反転
 */
export declare type YaxisMode = "follow" | "invert";

export { }
