# -*- coding: utf-8 -*-
"""
Created on Mon Oct 28 21:39:08 2024

@author: malij
"""

# -*- coding: utf-8 -*-
"""
Created on Wed Oct 23 19:05:38 2024

@author: malij
"""


import math
import random
# import numpy as np
import pickle


numberOfStories= 3
numberOfBays = 3


# damagePhases = [0.9, 0.8, 0.7, 0.6, 0.5, 0.4, 0.3, 0.2, 0.1]
# damagePhases = [0.5, 0.1]



#correct
# damagePhases = [0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9]
# damagePhases = [0.3, 0.3, 0.4, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9]
damagePhases = [0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9]


# damagePhases = [0.4,0.7]
# damagePhases = [0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5]


TS = 14000
# damagePhases = np.linspace (0.1, 0.5 , 5)
# print  (damagePhases)


transformers = []
elemIDs = []
transformer = 1

N0col = 1000  # Column element numbers
for level in range(1, numberOfStories + 1):
    for pier in range(1, numberOfBays + 2):
        elemID = N0col + level + pier * 100
        # print (transformer, "=", elemID)
        transformers.append(transformer)
        elemIDs.append(elemID)
        transformer += 1
        

        
        

N0beam = 2000  # Beam element numbers
M0 = 0

for level in range(2, numberOfStories + 2):
    for bay in range(1, numberOfBays + 1):
        elemID = N0beam + level + bay * 100
        # print (transformer, "=", elemID)
        transformers.append(transformer)
        elemIDs.append(elemID)
        transformer += 1



def generate_L (numberOfStories,numberOfBays, numberOfDamagePhases):
    # Generate all combinations of selecting r elements from objects:
    lenCombo = []
    M = (2*numberOfBays+1)*(numberOfStories)
    for r in range (1,M+1):
        lenDamageLocations = math.comb(M, r)
        lenDamageQuantities = numberOfDamagePhases ** r
        lenCombo.append(lenDamageLocations*lenDamageQuantities) 
    return lenCombo


def proportionally_sampler (L,TS):
    M = len(L)
    SP= sum(L)
    proportion = TS/SP
    N_samples = [] #a list of number of samples we would like to take for each member
    for Li in L:
        N_sample = Li*proportion
        if N_sample < 1: N_sample = 1
        min_N_Sample = min((0.1*Li),0.1*TS/M)
        if N_sample < min_N_Sample: N_sample = min_N_Sample
        N_samples.append(round(N_sample))
    

    return N_samples


def generate_random_numbers(count, min_value, max_value):
  random_numbers = []
  while len(random_numbers) < count:
    random_number = random.randint(min_value, max_value)
    random_numbers.append(random_number)
  return random_numbers


def generate_unique_random_numbers(count, min_value, max_value):
  random_numbers = []
  while len(random_numbers) < count:
    random_number = random.randint(min_value, max_value)
    if random_number not in random_numbers:
      random_numbers.append(random_number)
  random_numbers.sort()
  return random_numbers    



def generateSamples(numberOfStories,numberOfBays,numberOfDamagePhases, N_samples):
    AllSampled_damagedMembers = [] #=DL
    M = (2*numberOfBays+1)*(numberOfStories)
    for r in range (1,M+1):
        numberOfSamples = N_samples[r-1] # = S[i] in log
        Sampled_damagedMembers = []
        while len(Sampled_damagedMembers) < numberOfSamples:
            # print ("here",r)
            numberOfDamgaedMembers = len(AllSampled_damagedMembers)+1
            damageLocations  = generate_unique_random_numbers(numberOfDamgaedMembers, 1, M)
            # print ("here")

            for j in range (0,len(damageLocations)):
                for i in range (0,len(transformers)):
                    if damageLocations[j] == transformers[i]: damageLocations[j]=elemIDs[i]
            # print ("here")
    
            damageQuantities = generate_random_numbers(numberOfDamgaedMembers, 1, numberOfDamagePhases)
            for s in range (0,len(damageQuantities)):
                for k in range (0,len(damagePhases)):
                    if damageQuantities[s] == k+1: damageQuantities[s] = damagePhases[k]
            
            
            Sampled_damagedMembers.append((damageLocations, damageQuantities))
        
        AllSampled_damagedMembers.append(Sampled_damagedMembers)   
    return AllSampled_damagedMembers




       

# Assuming you have a list of n objects (beam and column elements):

numberOfDamagePhases = len(damagePhases)
L = generate_L(numberOfStories, numberOfBays, numberOfDamagePhases)

N_samples = proportionally_sampler(L, TS)

sampless= generateSamples(numberOfStories,numberOfBays,numberOfDamagePhases, N_samples)
#add intact structure to the samples
intact = [[([1],[1])]]

# np.save('samples.npy', sampless)

sampless = intact + sampless


print (L)
print(sum(L))
print (N_samples)
print(sum(N_samples))
b=0
for a in sampless:
    b=b+len(a)

print ("b=",b)
print(sampless[0])
# print(sampless[0][0])
# print(sampless[0][0][0])
# print(sampless[0][0][1])

print ("b=",b)
# print(sampless)
# print(sampless[1][0])
# print(sampless[1][0][0])
# print(sampless[1][0][1])
# print(sampless[1][0][1][1])


# print(sampless[3][0][0][2])

# print(sampless[20][0][0][5])

# print(sampless.shape)
        
# np.save('samples.npy', sampless)

# Save the variable to a text file
# with open('sampless.txt', 'w') as f:
#   f.write(str(sampless))
  
with open('sampless.pkl', 'wb') as f:
    pickle.dump(sampless, f)
  
# with open('samplessTest_21.pkl', 'wb') as f:
    # pickle.dump(sampless, f)
    
# with open('sampless.pkl', 'rb') as f:
#     loaded_list = pickle.load(f)
  
# Load the variable from the text file
# with open('sampless.txt', 'r') as f:
#   loaded_variable = f.read()
    
    
