import torch
import torch.nn as nn
from src.network import Conv2d


class MCNN(nn.Module):

    def __init__(self, bn=False):
        super(MCNN, self).__init__()

        self.branch1 = nn.Sequential(Conv2d(1, 16, 9, same_padding=True, bn=bn),
                                     nn.MaxPool2d(2),
                                     Conv2d(16, 32, 7, same_padding=True, bn=bn),
                                     nn.MaxPool2d(2),
                                     Conv2d(32, 16, 7, same_padding=True, bn=bn),
                                     Conv2d(16, 8, 7, same_padding=True, bn=bn))

        self.branch2 = nn.Sequential(Conv2d(1, 20, 7, same_padding=True, bn=bn),
                                     nn.MaxPool2d(2),
                                     Conv2d(20, 40, 5, same_padding=True, bn=bn),
                                     nn.MaxPool2d(2),
                                     Conv2d(40, 20, 5, same_padding=True, bn=bn),
                                     Conv2d(20, 10, 5, same_padding=True, bn=bn))

        self.branch3 = nn.Sequential(Conv2d(1, 24, 5, same_padding=True, bn=bn),
                                     nn.MaxPool2d(2),
                                     Conv2d(24, 48, 3, same_padding=True, bn=bn),
                                     nn.MaxPool2d(2),
                                     Conv2d(48, 24, 3, same_padding=True, bn=bn),
                                     Conv2d(24, 12, 3, same_padding=True, bn=bn))

        self.branch4 = nn.Sequential(Conv2d(1, 28, 3, same_padding=True, bn=bn),
                                     nn.MaxPool2d(2),
                                     Conv2d(28, 56, 1, same_padding=True, bn=bn),
                                     nn.MaxPool2d(2),
                                     Conv2d(56, 28, 1, same_padding=True, bn=bn),
                                     Conv2d(28, 14, 1, same_padding=True, bn=bn))
        self.fuse = nn.Sequential(Conv2d(44, 1, 1, same_padding=True, bn=bn))

    def forward(self, im_data):
        x1 = self.branch1(im_data)
        x2 = self.branch2(im_data)
        x3 = self.branch3(im_data)
        x4 = self.branch4(im_data)
        x = torch.cat((x1, x2, x3, x4), 1)
        x = self.fuse(x)

        return x
