#  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 SMDButtonWizard(HelpfulFootprintWizardPlugin.HelpfulFootprintWizardPlugin):

    def GetName(self):
        return "Button"

    def GetDescription(self):
        return "SMD Button Footprint Wizard"

    def GenerateParameterList(self):
        self.AddParam("Pads", "width", self.uMM, 12)
        self.AddParam("Pads", "length", self.uMM, 14)
        self.AddParam("Pads", "height", self.uMM, 7)        
        self.AddParam("Pads", "pad width", self.uMM, 3)
        self.AddParam("Pads", "pad length", self.uMM, 5)
        self.AddParam("Pads", "h_pitch", self.uMM, 10)
        self.AddParam("Pads", "v_pitch", self.uMM, 10)

    def CheckParameters(self):
        return
     
    def GetReferencePrefix(self):
        return "SW"

    def GetValue(self):        
        width = self.parameters["Pads"]["width"] / 100000
        length = self.parameters["Pads"]["length"] / 100000
        height = self.parameters["Pads"]["height"] / 100000
        width, wfrag = divmod(width, 10)
        height, hfrag = divmod(height, 10)
        length, lfrag = divmod(length, 10)
        if wfrag==0:
            t_width = "%d" % width
        else:
            t_width = "%d.%d" % (width, wfrag)
        if hfrag==0:
            t_height = "%d" % height
        else:
            t_height = "%d.%d" % (height, hfrag)
        if lfrag==0:
            t_length = "%d" % length
        else:
            t_length = "%d.%d" % (length, lfrag)        
        return "pbutton_%sx%s_H%s" % (t_width, t_length, t_height) 

    def BuildThisFootprint(self):
        pads = self.parameters["Pads"]       
        width = pads["width"]
        height = pads["height"]
        length = pads["length"]
        pad_length = pads["pad length"]
        pad_width = pads["pad width"]
        h_pitch = pads["h_pitch"]
        v_pitch = pads["v_pitch"]        
        normal_pad = PA.PadMaker(self.module).SMDPad(pad_width, pad_length, pcbnew.PAD_RECT)        
        pin1Pos = pcbnew.wxPoint(- h_pitch / 2, 0)
        array_1 = PA.PadLineArray(normal_pad, 2, v_pitch, True, pin1Pos)
        array_1.SetFirstPadInArray(1)
        array_1.AddPadsToModule(self.draw)
        pin1Pos = pcbnew.wxPoint(h_pitch / 2, 0)        
        array_2 = PA.PadLineArray(normal_pad, 2, v_pitch, True, pin1Pos)
        array_2.SetFirstPadInArray(1)
        array_2.AddPadsToModule(self.draw)
        m_clearance = pcbnew.FromMM(0.5)
        r = (min(width, length) * 0.7) / 2     
        arc_startx = ((h_pitch - pad_length) / 2) - m_clearance
        arc_starty = ((v_pitch - pad_width) / 2) - m_clearance
        if r**2 > arc_startx**2 + arc_starty**2:
            angle_interceptx = math.asin(arc_startx / r)
            sy = -(math.cos(angle_interceptx) * r)                        
            angle_intercepty = math.acos(arc_starty / r)
            sx = -(math.sin(angle_intercepty) * r)                
            self.draw.Arc(0, 0, sx, -arc_starty, -(2 * (math.pi / 2 - angle_intercepty)) * 572.9578)
            self.draw.Arc(0, 0, -sx, arc_starty, -(2 * (math.pi / 2 - angle_intercepty)) * 572.9578)
            self.draw.Arc(0, 0, -arc_startx, sy, 2 * angle_interceptx * 572.9578)
            self.draw.Arc(0, 0, arc_startx, -sy, 2 * angle_interceptx * 572.9578)
        else:
            self.draw.Circle(0,0,r)  
                    
        xcomp = (h_pitch - length) / 2 > (pad_length / 2) + m_clearance
        ycomp = (v_pitch - width) / 2 > (pad_width / 2) + m_clearance
        xfree = abs((v_pitch - width) / 2) > (pad_width / 2) + m_clearance
        yfree = abs((h_pitch - length) / 2) > (pad_length / 2) + m_clearance
        sx = (h_pitch - pad_length) / 2 - m_clearance
        sxc = (h_pitch + pad_length) / 2 + m_clearance
        sy = (v_pitch - pad_width) / 2 - m_clearance
        syc = (v_pitch + pad_width) / 2 + m_clearance
        if xcomp or xfree:
            self.draw.Line(-length / 2, -width / 2, length / 2, -width / 2)
            self.draw.Line(-length / 2, width / 2, length / 2, width / 2)
        else:
            self.draw.Line(-sx, -width / 2, sx, -width / 2)
            self.draw.Line(-sx, width / 2, sx, width / 2)
            if yfree:
                self.draw.Line(-length / 2, -width / 2, -sxc, -width / 2)
                self.draw.Line(-length / 2, width / 2, -sxc, width / 2)
                self.draw.Line(length / 2, -width / 2, sxc, -width / 2)
                self.draw.Line(length / 2, width / 2, sxc, width / 2)
        if ycomp or yfree:
            self.draw.Line(-length / 2, -width / 2, -length / 2, width / 2)
            self.draw.Line(length / 2, -width / 2, length / 2, width / 2)
        else:
            self.draw.Line(-length / 2, -sy, -length / 2, sy)
            self.draw.Line(length / 2, -sy, length / 2, sy)
            if xfree:
                self.draw.Line(-length / 2, -width / 2, -length / 2, -syc)
                self.draw.Line(length / 2, -width / 2, length / 2, -syc)
                self.draw.Line(-length / 2, width / 2, -length / 2, syc)
                self.draw.Line(length / 2, width / 2, length / 2, syc)
                
        text_size = pcbnew.FromMM(1.2) 
        text_offset = text_size + max(width, v_pitch + pad_width) / 2
        self.draw.Value(0, text_offset, text_size)
        self.draw.Reference(0, -text_offset, text_size)

SMDButtonWizard().register()
