<commit_before>//
// Copyright (c) 2016-2017 wag it GmbH.
// License: MIT
//

import Foundation
import UIKit

/**
    Layout that uses only the reference side for measurement, or the smaller side if not specified.
    Mirrors layoutMargins and frame of its child.
    When setting the frame of its element, it uses the smaller side to ensure the square fits in the available space.
*/
public struct BayaSquareLayout: BayaLayout {
    public var layoutMargins: UIEdgeInsets {
        return element.layoutMargins
    }
    public var frame: CGRect {
        return element.frame
    }
    public var layoutModes: BayaLayoutOptions.Modes {
        // BayaSquareLayout wants its parent to used the measured sizes.
        return BayaLayoutOptions.Modes.default
    }
    private var element: BayaLayoutable
    private let referenceSide: BayaLayoutOptions.Orientation?

    init(
        element: BayaLayoutable,
        referenceSide: BayaLayoutOptions.Orientation?) {
        self.element = element
        self.referenceSide = referenceSide
    }

    mutating public func layoutWith(frame: CGRect) {
        element.layoutWith(frame: CGRect(
            origin: frame.origin,
            size: squareSizeBasedOnReferenceSide(frame.size)))
    }

    public mutating func sizeThatFits(_ size: CGSize) -> CGSize {
        let adjustedSize = squareSizeBasedOnReferenceSide(size)
        let _ = element.sizeThatFits(adjustedSize)
        return adjustedSize
    }

    private func squareSizeBasedOnReferenceSide(_ size: CGSize) -> CGSize {
        switch referenceSide {
        case .some(.horizontal):
            return size.toSquareFromWidth()
        case .some(.vertical):
            return size.toSquareFromHeight()
        case .none:
            return size.toSquare()
        }
    }
}

private extension CGRect {
    func toSquare() -> CGRect {
        return CGRect(origin: origin, size: size.toSquare())
    }
}

private extension CGSize {
    func toSquareFromWidth() -> CGSize {
        return CGSize(width: width, height: width)
    }

    func toSquareFromHeight() -> CGSize {
        return CGSize(width: height, height: height)
    }

    func toSquare() -> CGSize {
        let sideLength = min(width, height)
        return CGSize(width: sideLength, height: sideLength)
    }
}

// MARK: Square shortcuts.

public extension BayaLayoutable {
    func layoutAsSquare() -> BayaSquareLayout {
        return BayaSquareLayout(
            element: self,
            referenceSide: nil)
    }

    func layoutAsSquare(referenceSide: BayaLayoutOptions.Orientation)
            -> BayaSquareLayout {
        return BayaSquareLayout(
            element: self,
            referenceSide: referenceSide)
    }
}
<commit_msg>(fix) measure element if no reference side is specified<commit_after>//
// Copyright (c) 2016-2017 wag it GmbH.
// License: MIT
//

import Foundation
import UIKit

/**
    Layout that uses only the reference side for measurement, or the smaller side if not specified.
    Mirrors layoutMargins and frame of its child.
    When setting the frame of its element, it uses the smaller side to ensure the square fits in the available space.
*/
public struct BayaSquareLayout: BayaLayout {
    public var layoutMargins: UIEdgeInsets {
        return element.layoutMargins
    }
    public var frame: CGRect {
        return element.frame
    }
    public var layoutModes: BayaLayoutOptions.Modes {
        // BayaSquareLayout wants its parent to used the measured sizes.
        return BayaLayoutOptions.Modes.default
    }
    private var element: BayaLayoutable
    private let referenceSide: BayaLayoutOptions.Orientation?

    init(
        element: BayaLayoutable,
        referenceSide: BayaLayoutOptions.Orientation?) {
        self.element = element
        self.referenceSide = referenceSide
    }

    mutating public func layoutWith(frame: CGRect) {
        element.layoutWith(frame: CGRect(
            origin: frame.origin,
            size: squareSizeBasedOnReferenceSide(frame.size)))
    }

    public mutating func sizeThatFits(_ size: CGSize) -> CGSize {
        if referenceSide != nil {
            return squareSizeBasedOnReferenceSide(size)
        } else {
            let fit = element.sizeThatFits(size.toSquare())
            let bigSide = max(fit.height, fit.width)
            return CGSize(width: bigSide, height: bigSide)
        }
    }

    private func squareSizeBasedOnReferenceSide(_ size: CGSize) -> CGSize {
        switch referenceSide {
        case .some(.horizontal):
            return size.toSquareFromWidth()
        case .some(.vertical):
            return size.toSquareFromHeight()
        case .none:
            return size.toSquare()
        }
    }
}

private extension CGRect {
    func toSquare() -> CGRect {
        return CGRect(origin: origin, size: size.toSquare())
    }
}

private extension CGSize {
    func toSquareFromWidth() -> CGSize {
        return CGSize(width: width, height: width)
    }

    func toSquareFromHeight() -> CGSize {
        return CGSize(width: height, height: height)
    }

    func toSquare() -> CGSize {
        let sideLength = min(width, height)
        return CGSize(width: sideLength, height: sideLength)
    }
}

// MARK: Square shortcuts.

public extension BayaLayoutable {
    func layoutAsSquare() -> BayaSquareLayout {
        return BayaSquareLayout(
            element: self,
            referenceSide: nil)
    }

    func layoutAsSquare(referenceSide: BayaLayoutOptions.Orientation)
            -> BayaSquareLayout {
        return BayaSquareLayout(
            element: self,
            referenceSide: referenceSide)
    }
}

{'fraction_non_alphanumeric': 0.07794273594909862, 'fraction_numerical': 0.002827854365500177, 'mean_word_length': 2.4824615384615383, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 19, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4421599', 'n_tokens_mistral': 1615, 'n_tokens_neox': 1526, 'n_words': 453}