################################################################################################
# Copyright 2023 GlobalFoundries PDK Authors
#
# 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
#
#     https://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.
################################################################################################

#================================================
# --------------- CUSTOM CLASSES ----------------
#================================================

#=========== CUSTOM READER ===========
class SubcircuitModelsReader < RBA::NetlistSpiceReaderDelegate
    def parse_element(sup, element)
      begin
        super
      rescue
        case element
        when 'C'
          super("#{sup} C=2e-16", element)
        when 'R'
          super("#{sup} R=0", element)
        else
          super
        end
      end
    end
    
    # implements the delegate interface:
    # take and translate the element
    def element(circuit, ele, name, model, value, nets, params)
      case ele
      when 'C'
        error('Capacitor needs two nodes') if nets.size != 2
  
        # provide a device class
        cls = circuit.netlist.device_class_by_name(model)
        unless cls
          cls = RBA::DeviceClassCapacitor.new
          cls.name = model
          circuit.netlist.add(cls)
        end
  
        # create a device
        device = circuit.create_device(cls, name)
  
        # and configure the device
        %w[A B].each_with_index do |t, index|
          device.connect_terminal(t, nets[index])
        end
  
        # parameters in the model are given in micrometer units, so
        # we need to translate the parameter values from SI to um values:
        device.set_parameter('A', ((params['W'] || 0.0) * (params['L'] || 0.0)) * 1e12)
        device.set_parameter('P', ((params['W'] || 0.0) + (params['L'] || 0.0)) * 2e6)
        device.set_parameter('C', (params['C'] || 0.0))
  
      when 'R'
        case nets.size
        when 3
          # provide a device class
          cls = circuit.netlist.device_class_by_name(model)
          unless cls
            cls = RBA::DeviceClassResistorWithBulk.new
            cls.name = model
            circuit.netlist.add(cls)
          end
  
          # create a device
          device = circuit.create_device(cls, name)
  
          # and configure the device
          %w[A B W].each_with_index do |t, index|
            device.connect_terminal(t, nets[index])
          end
  
        when 2
          # provide a device class
          cls = circuit.netlist.device_class_by_name(model)
          unless cls
            cls = RBA::DeviceClassResistor.new
            cls.name = model
            circuit.netlist.add(cls)
          end
  
          # create a device
          device = circuit.create_device(cls, name)
  
          # and configure the device
          %w[A B].each_with_index do |t, index|
            device.connect_terminal(t, nets[index])
          end
  
        else
          error('Resistor needs two or three nodes')
  
        end
  
        # parameters in the model are given in micrometer units, so
        # we need to translate the parameter values from SI to um values:
        device.set_parameter('W', ((params['W'] || 0.0) * (params['PAR'] || 1.0)) * 1e6)
        device.set_parameter('L', ((params['L'] || 0.0) * (params['S'] || 1.0)) * 1e6)
        device.set_parameter('R', (params['R'] * (params['S'] || 1.0) / (params['PAR'] || 1.0)))
  
      else
        return super
  
      end
      true
    end
  end
  
  # 4 terminals resistor device extractor
  class BResistor < RBA::DeviceClassResistorWithBulk
    def initialize
      super
      enable_parameter('R', false)
      enable_parameter('W', true)
      enable_parameter('L', true)
    end
  end
  
  # 3 terminals resistor device extractor
  class NResistor < RBA::DeviceClassResistor
    def initialize
      super
      enable_parameter('R', false)
      enable_parameter('W', true)
      enable_parameter('L', true)
    end
  end

  
  # MIMCAP device extractor
  class MIMCap < RBA::DeviceClassCapacitor
    def initialize
      super
      enable_parameter('C', true)
      enable_parameter('A', true)
      enable_parameter('P', true)
    end
  end

  class VarCap < RBA::DeviceClassCapacitorWithBulk
    def initialize
      super
      enable_parameter("C", false)
      enable_parameter("A", true)
      enable_parameter("P", true)
    end
  end