// Copyright 2026 International Digital Economy Academy
//
// 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.

///|
pub struct ChannelCountConverter {
  inner : DynSource
  to : ChannelCount
}

///|
pub fn[S : Source] ChannelCountConverter::new(
  input : S,
  from : ChannelCount,
  to : ChannelCount,
) -> ChannelCountConverter {
  guard from > 0 else { panic() }
  guard to > 0 else { panic() }
  let src = to_dyn(input)
  guard src.channels() == from else { panic() }
  { inner: channel_convert(src, to), to }
}

///|
pub fn ChannelCountConverter::inner_mut(
  self : ChannelCountConverter,
) -> DynSource {
  self.inner
}

///|
pub fn ChannelCountConverter::into_inner(
  self : ChannelCountConverter,
) -> DynSource {
  self.inner
}

///|
pub impl Source for ChannelCountConverter with next(
  self : ChannelCountConverter,
) {
  self.inner.next()
}

///|
pub impl Source for ChannelCountConverter with channels(
  self : ChannelCountConverter,
) {
  self.to
}

///|
pub impl Source for ChannelCountConverter with sample_rate(
  self : ChannelCountConverter,
) {
  self.inner.sample_rate()
}

///|
pub impl Source for ChannelCountConverter with current_span_len(
  _self : ChannelCountConverter,
) {
  _self.inner.current_span_len()
}

///|
pub impl Source for ChannelCountConverter with total_duration(
  _self : ChannelCountConverter,
) {
  _self.inner.total_duration()
}

///|
pub impl Source for ChannelCountConverter with try_seek(
  _self : ChannelCountConverter,
  pos : @moon_cpal.Duration,
) -> Unit raise SeekError {
  _self.inner.try_seek(pos)
}

///|
pub struct SampleRateConverter {
  inner : DynSource
  to : SampleRate
  channels : ChannelCount
}

///|
pub fn[S : Source] SampleRateConverter::new(
  input : S,
  from : SampleRate,
  to : SampleRate,
  num_channels : ChannelCount,
) -> SampleRateConverter {
  guard from > 0 else { panic() }
  guard to > 0 else { panic() }
  guard num_channels > 0 else { panic() }
  let src = to_dyn(input)
  guard src.sample_rate() == from else { panic() }
  guard src.channels() == num_channels else { panic() }
  { inner: sample_rate_convert(src, to), to, channels: num_channels }
}

///|
pub fn SampleRateConverter::inner_mut(self : SampleRateConverter) -> DynSource {
  self.inner
}

///|
pub fn SampleRateConverter::into_inner(self : SampleRateConverter) -> DynSource {
  self.inner
}

///|
pub impl Source for SampleRateConverter with next(self : SampleRateConverter) {
  self.inner.next()
}

///|
pub impl Source for SampleRateConverter with channels(
  self : SampleRateConverter,
) {
  self.channels
}

///|
pub impl Source for SampleRateConverter with sample_rate(
  self : SampleRateConverter,
) {
  self.to
}

///|
pub impl Source for SampleRateConverter with current_span_len(
  _self : SampleRateConverter,
) {
  _self.inner.current_span_len()
}

///|
pub impl Source for SampleRateConverter with total_duration(
  _self : SampleRateConverter,
) {
  _self.inner.total_duration()
}

///|
pub impl Source for SampleRateConverter with try_seek(
  _self : SampleRateConverter,
  pos : @moon_cpal.Duration,
) -> Unit raise SeekError {
  _self.inner.try_seek(pos)
}

///|
pub struct SampleTypeConverter {
  inner : DynSource
}

///|
pub fn[S : Source] SampleTypeConverter::new(input : S) -> SampleTypeConverter {
  { inner: to_dyn(input) }
}

///|
pub fn SampleTypeConverter::inner_mut(self : SampleTypeConverter) -> DynSource {
  self.inner
}

///|
pub fn SampleTypeConverter::into_inner(self : SampleTypeConverter) -> DynSource {
  self.inner
}

///|
pub impl Source for SampleTypeConverter with next(self : SampleTypeConverter) {
  self.inner.next()
}

///|
pub impl Source for SampleTypeConverter with channels(
  self : SampleTypeConverter,
) {
  self.inner.channels()
}

///|
pub impl Source for SampleTypeConverter with sample_rate(
  self : SampleTypeConverter,
) {
  self.inner.sample_rate()
}

///|
pub impl Source for SampleTypeConverter with current_span_len(
  _self : SampleTypeConverter,
) {
  _self.inner.current_span_len()
}

///|
pub impl Source for SampleTypeConverter with total_duration(
  _self : SampleTypeConverter,
) {
  _self.inner.total_duration()
}

///|
pub impl Source for SampleTypeConverter with try_seek(
  _self : SampleTypeConverter,
  pos : @moon_cpal.Duration,
) -> Unit raise SeekError {
  _self.inner.try_seek(pos)
}