# -*- coding: utf-8 -*-
#
# A script to Snap modules to selected Grid for kicad_pcb
# requirements: KiCAD pcbnew >= 4.0
# copyright Maurice easyw
# 
#

#import snaptogrid; import importlib; importlib.reload(snaptogrid)

__version__ = '1.0.1'
import sys, os
import pcbnew
import datetime
import wx
from pcbnew import *

use_grid_origin = True

gridReference = 2.54 #1.27 #mm pcbnew.FromMM(1.0) #0.1mm

gridSizeMM = gridReference

#from . import Send2GridDlg

sys.path.append(os.path.dirname(__file__))

debug = False
def wxLogDebug(msg,dbg):
    """printing messages only if show is omitted or True"""
    if dbg == True:
        wx.LogMessage(msg)
#
 
#class Snap2Grid_Dlg(Snap2GridDlg.Snap2GridDlg):
#    # from https://github.com/MitjaNemec/Kicad_action_plugins
#    # hack for new wxFormBuilder generating code incompatible with old wxPython
#    # noinspection PyMethodOverriding
#    def SetSizeHints(self, sz1, sz2):
#        if wx.__version__ < '4.0':
#            self.SetSizeHintsSz(sz1, sz2)
#        else:
#            super(RoundTrack_Dlg, self).SetSizeHints(sz1, sz2)
#
#    # def onDeleteClick(self, event):
#    #     return self.EndModal(wx.ID_DELETE)
#    # 
#    # def onConnectClick(self, event):
#    #     return self.EndModal(wx.ID_REVERT)
#
#    def __init__(self,  parent):
#        import wx
#        Send2GridDlg.Send2GridDlg.__init__(self, parent)
#        #self.GetSizer().Fit(self)
#        self.SetMinSize(self.GetSize())
#        #self.m_buttonDelete.Bind(wx.EVT_BUTTON, self.onDeleteClick)
#        #self.m_buttonReconnect.Bind(wx.EVT_BUTTON, self.onConnectClick)
#        #if wx.__version__ < '4.0':
#        #    self.m_buttonReconnect.SetToolTipString( u"Select two converging Tracks to re-connect them\nor Select tracks including one round corner to be straighten" )
#        #    self.m_buttonRound.SetToolTipString( u"Select two connected Tracks to round the corner\nThen choose distance from intersection and the number of segments" )
#        #else:
#        #    self.m_buttonReconnect.SetToolTip( u"Select two converging Tracks to re-connect them\nor Select tracks including one round corner to be straighten" )
#        #    self.m_buttonRound.SetToolTip( u"Select two connected Tracks to round the corner\nThen choose distance from intersection and the number of segments" )
#
# Python plugin stuff
class snap_to_grid( pcbnew.ActionPlugin ):
    """
    A plugin to Snap modules to selected Grid for kicad_pcb
    requirements: KiCAD pcbnew >= 4.0
    
    """
    def defaults( self ):
        """
        Method defaults must be redefined
        self.name should be the menu label to use
        self.category should be the category (not yet used)
        self.description should be a comprehensive description
          of the plugin
        """
        self.name = "Snap Selected Module(s) to Grid\nversion "+__version__
        self.category = "Modify PCB"
        self.description = "Automaticaly Snap Selected Module(s) to Grid on an existing PCB"
        #self.pcbnew_icon_support = hasattr(self, "show_toolbar_button")
        self.show_toolbar_button = True
        self.icon_file_name = os.path.join(os.path.dirname(__file__), './snap2grid.png')
    #

    def Run(self):
        #self.pcb = GetBoard()
        import sys,os
        #mm_ius = 1000000.0
        
        pcb = pcbnew.GetBoard()
        gridOrigin = pcb.GetGridOrigin()
        auxOrigin = pcb.GetAuxOrigin()
        content=''
        locked_fp=''
        #wxPoint(77470000, 135890000)
        for module in pcb.GetModules(): 
            if module.IsSelected():
                if use_grid_origin:
                    mpx = module.GetPosition().x - gridOrigin.x
                    mpy = module.GetPosition().y - gridOrigin.y
                    print(mpx,mpy)
                    mpxOnG = int(mpx/FromMM(gridSizeMM))*FromMM(gridSizeMM)+ gridOrigin.x
                    mpyOnG = int(mpy/FromMM(gridSizeMM))*FromMM(gridSizeMM)+ gridOrigin.y
                    print(mpxOnG,mpyOnG)
                    locked=''
                    if not module.IsLocked():
                        module.SetPosition(wxPoint(mpxOnG,mpyOnG))
                    else:
                        locked='LOCKED'
                    X_POS=str(module.GetPosition().x) # - gridOrigin.x)
                    #X_POS='{0:.4f}'.format(pcbnew.ToMM(module.GetPosition().x - gridOrigin.x ))
                    X_POS="{0:<11}".format(X_POS)
                    Y_POS=str(module.GetPosition().y) # - gridOrigin.y)
                    Y_POS="{0:<11}".format(Y_POS)
                    ## mpOnGx = PutOnGridMM(module.GetPosition().x, gridSizeMM)
                    ## mpOnGy = PutOnGridMM(module.GetPosition().y, gridSizeMM)
                    ## module.SetPosition(wxPoint(mpOnGx,mpOnGy))
                    #module.SetPosition(wxPoint(mpOnGx+FromMM(100.0),mpOnGy+FromMM(2.0)))
                    #module.SetOrientation(10)
                    #Y_POS='{0:.4f}'.format(-1*pcbnew.ToMM(module.GetPosition().y - gridOrigin.y))
                # else:
                #     mpx = module.GetPosition().x - auxOrigin().x
                #     mpy = module.GetPosition().y - auxOrigin().y
                #     X_POS='{0:.4f}'.format(pcbnew.ToMM(module.GetPosition().x - auxOrigin().x ))
                #     X_POS="{0:<11}".format(X_POS)
                #     Y_POS='{0:.4f}'.format(-1*pcbnew.ToMM(module.GetPosition().y - auxOrigin().y))
                #     Y_POS="{0:<11}".format(Y_POS)
                Reference="{0:<10}".format(str(module.GetReference()))
                Value = str(module.GetValue())
                Value=(Value[:17] + '..') if len(Value) > 19 else Value
                Value="{0:<20}".format(Value)
                Rotation='{0:.1f}'.format((module.GetOrientation()/10))
                Rotation="{0:>6}".format(Rotation)+'  '
                if module.GetLayer() == 0:
                    Layer="  top"
                else:
                    Layer="  bottom"
                #Side="## Side :"+Layer+lsep
                Layer="{0:<10}".format(Layer)
                content+=Reference
                if 'LOCKED' in locked:
                    locked_fp+=Reference + ' LOCKED'+'\n' #os.linesep
                #content+=Value
                content+=X_POS
                content+=Y_POS
                #content+=str(mpOnGx)
                #content+=str(mpOnGy)
                content+=str(mpxOnG)
                content+=str(mpyOnG)
                content+=Layer+'\n' #os.linesep
        if len(content)>0:
            content+=str(pcbnew.FromMM(gridReference))
            wxLogDebug(content,debug)
            if len (locked_fp)>0:
                locked_fp+='\n'+'NOT Moved'
                wxLogDebug(locked_fp,True)
        else:
            wxLogDebug('No Modules Selected',True)
        Refresh()
        #return content

        #if 0:
        #    #from https://github.com/MitjaNemec/Kicad_action_plugins
        #    #hack wxFormBuilder py2/py3
        #    _pcbnew_frame = [x for x in wx.GetTopLevelWindows() if x.GetTitle().lower().startswith('pcbnew')][0]
        #    #aParameters = RoundTrackDlg(None)
        #    aParameters = RoundTrack_Dlg(_pcbnew_frame)
        #    #aParameters = RoundTrack_DlgEx(_pcbnew_frame)
        #    aParameters.Show()
        #    #end hack
        #    aParameters.m_distanceMM.SetValue("5")
        #    aParameters.m_segments.SetValue("16")
        #    aParameters.m_bitmap1.SetBitmap(wx.Bitmap( os.path.join(os.path.dirname(os.path.realpath(__file__)), "round_track_help.png") ) )
        #    modal_result = aParameters.ShowModal()
        #    segments = self.CheckSegmentsInput(
        #        aParameters.m_segments.GetValue(), "number of segments")
        #    distI = FromMM(self.CheckDistanceInput(aParameters.m_distanceMM.GetValue(), "distance from intersection"))
        #    if segments is not None and distI is not None:
        #        if modal_result == wx.ID_OK:
        #            Round_Selection(pcb, distI, segments)
        #        elif modal_result == wx.ID_DELETE:
        #            Delete_Segments(pcb)
        #            #wx.LogMessage('Round Segments on Track Net Deleted')
        #        elif modal_result == wx.ID_REVERT:
        #            wxLogDebug('Connecting Tracks',debug)
        #            Connect_Segments(pcb)
        #        else:
        #            None  # Cancel
        #    else:
        #        None  # Invalid input
        #    aParameters.Destroy()
        
        
        # wxLogDebug('showing Selected Tracks',debug)
        # wx.LogMessage('Select Tracks to calculate the Length\nor One Pad to select connected Tracks')
#
 
