import warnings


def flatten(geoms):
    """Flatten a list of geometries into a single geometry object

    Combine geometries by iteratively union-ing neighbors (according to index)
     * example, given a list of geometries (A,B,C,D,E,F,G,H,I,J):
          [ A  B  C  D  E  F  G  H  I  J ]
          [  AB    CD    EF    GH    IJ  ]
          [    ABCD        EFGH      IJ  ]
          [        ABCDEFGH          IJ  ]
          [               ABCDEFGHIJ     ]  <- This becomes the resulting geometry  

    Example:
    --------
        * A list of Polygons/Multipolygons will become a single Multipolygon
        * A list of Linestrings/MultiLinestrings will become a single MultiLinestring

    """
    if not isinstance(geoms, list):
        geoms = list(geoms)
        try:  # geoms is not a list, but it might be iterable
            geoms = list(geoms)
        except:
            raise ValueError("argument must be a list of geometries")

    if len(geoms) == 0:
        return None

    # Begin flattening
    while(len(geoms) > 1):
        newGeoms = []
        for gi in range(0, len(geoms), 2):

            try:
                if not geoms[gi].IsValid():
                    warnings.warn(
                        "WARNING: Invalid Geometry encountered", UserWarning)
                if not geoms[gi + 1].IsValid():
                    warnings.warn(
                        "WARNING: Invalid Geometry encountered", UserWarning)

                newGeoms.append(geoms[gi].Union(geoms[gi + 1]))
            except IndexError:  # should only occur when length of geoms is odd
                newGeoms.append(geoms[gi])

        geoms = newGeoms
    return geoms[0]