#  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 2 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, write to the Free Software
#  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
#  MA 02110-1301, USA.
#

from __future__ import division
import math
import pcbnew

import HelpfulFootprintWizardPlugin
import PadArray as PA


class ChokeWizard(HelpfulFootprintWizardPlugin.HelpfulFootprintWizardPlugin):

    def GetName(self):
        return "Choke"

    def GetDescription(self):
        return "SMD Choke Footprint Wizard v1.1"

    def GenerateParameterList(self):
        self.AddParam("Pads", "size", self.uMM, 12)
        self.AddParam("Pads", "height", self.uMM, 7)
        self.AddParam("Pads", "pad clearance", self.uMM, 7)
        self.AddParam("Pads", "pad width", self.uMM, 3)
        self.AddParam("Pads", "pad length", self.uMM, 5)
        self.AddParam("Pads", "style", self.uNatural, 1)
        self.AddParam("Style 2", "A", self.uMM, 8)
        self.AddParam("Style 2", "B", self.uMM, 17)
        #self.AddParam("Pads", "marking width", self.uMM, 2)

    def CheckParameters(self):
        self.CheckParamInt("Pads", "*style")
     
    def GetReferencePrefix(self):
        return "L"

    def GetValue(self):
        style = self.parameters["Pads"]["*style"]
        size = self.parameters["Pads"]["size"] / 100000
        height = self.parameters["Pads"]["height"] / 100000
        s2_b = self.parameters["Style 2"]["B"] / 100000
        size, sfrag = divmod(size, 10)
        height, hfrag = divmod(height, 10)
        s2_b, bfrag = divmod(s2_b, 10)
        if sfrag==0:
            t_size = "%d" % size
        else:
            t_size = "%d.%d" % (size, sfrag)
        if hfrag==0:
            t_height = "%d" % height
        else:
            t_height = "%d.%d" % (height, hfrag)
        if bfrag==0:
            t_b = "%d" % s2_b
        else:
            t_b = "%d.%d" % (s2_b, bfrag)
        if style == 1:
            t_b = t_size
        return "l_choke_%sx%s_H%s" % (t_b, t_size, t_height) 

    def BuildThisFootprint(self):
        pads = self.parameters["Pads"]
        style2 = self.parameters["Style 2"]
        s2_a = style2["A"]
        s2_b = style2["B"]
        size = pads["size"]
        height = pads["height"]
        pad_length = pads["pad length"]
        pad_width = pads["pad width"]
        pad_offset = pads["pad clearance"]
        style = pads["*style"]
        #m_width = pads["marking width"]
        m_width = size / 5        
        normal_pad = PA.PadMaker(self.module).SMDPad(pad_length, pad_width, pcbnew.PAD_RECT)        
        pin1Pos = pcbnew.wxPoint(0, 0)
        array = PA.PadLineArray(normal_pad, 2, pad_width + pad_offset, False, pin1Pos)
        array.SetFirstPadInArray(1)
        array.AddPadsToModule(self.draw) 
        m_clearance = pcbnew.FromMM(0.5)
        if style == 3:
            r = size / 2 
        else:
            r = (size * 0.9) / 2      
        arc_startx = (pad_offset / 2) - m_clearance
        arc_starty = (pad_length / 2) + m_clearance
        if r > arc_startx:
            angle_intercept = math.asin(arc_startx / r)
            sy = -(math.cos(angle_intercept) * r)            
            if abs(sy) > arc_starty:             
                angle_intercept = math.acos(arc_starty / r)
                sx = -(math.sin(angle_intercept) * r)                
                self.draw.Arc(0, 0, sx, -arc_starty, (2 * angle_intercept) * 572.9578)
                self.draw.Arc(0, 0, -sx, arc_starty, (2 * angle_intercept) * 572.9578)
            else:
                self.draw.Arc(0, 0, arc_startx, sy, -(2 * angle_intercept) * 572.9578)
                self.draw.Arc(0, 0, -arc_startx, -sy, -(2 * angle_intercept) * 572.9578)
        else:
            self.draw.Circle(0,0,r)
        if style == 1:
            if abs(size - (pad_offset + pad_width)) < pad_width + m_clearance:
                self.draw.Polyline([  
                    (- size / 2, -arc_starty),
                    (- size / 2, - size / 2),
                    (size / 2, - size / 2),
                    (size / 2, -arc_starty)         
                ])  
                self.draw.Polyline([  
                    (- size / 2, arc_starty),
                    (- size / 2,  size / 2),
                    (size / 2,  size / 2),
                    (size / 2, arc_starty)         
                ]) 
            else:
                self.draw.Box(0,0,size,size)
        if style == 2:
            self.draw.Polyline([  
                    (-s2_b / 2, -arc_starty),
                    (-s2_a / 2, - size / 2),
                    (s2_a / 2, - size / 2),
                    (s2_b / 2, -arc_starty)         
                ])  
            self.draw.Polyline([  
                    (-s2_b / 2, arc_starty),
                    (-s2_a / 2, size / 2),
                    (s2_a / 2, size / 2),
                    (s2_b / 2, arc_starty)         
                ])
            m = ((size / 2) - arc_starty) / ((s2_b - s2_a) / 2)
            sy = ((s2_b - size) / 2) * m + arc_starty
            if abs(size - (pad_offset + pad_width)) < pad_width + m_clearance:
                self.draw.Line(-size / 2, -arc_starty, -size / 2, -sy)
                self.draw.Line(-size / 2, arc_starty, -size / 2, sy)
                self.draw.Line(size / 2, -arc_starty, size / 2, -sy)
                self.draw.Line(size / 2, arc_starty, size / 2, sy)              
            else:
                self.draw.Line(-size / 2, sy, -size / 2, -sy)
                self.draw.Line(size / 2, sy, size / 2, -sy)
        # m_offs = self.draw.GetWidth() / 1.1 # marking line offset
        # m_num = int(round(m_width / m_offs, 0))        
        # for i in range(1,m_num):
            # offs = i * m_offs
            # angle_intercept = math.acos((r-offs)/r)
            # y = -(math.sin(angle_intercept) * r - m_offs / 2)
            # self.draw.VLine(-r+offs,y,abs(y*2))  
        text_size = pcbnew.FromMM(1.2) 
        text_offset = text_size + size / 2
        self.draw.Value(0, text_offset, text_size)
        self.draw.Reference(0, -text_offset, text_size)

ChokeWizard().register()
